SpringMVC基础

文章目录

  • SpringMVC基础
    • MVC理论基础
    • 第一个SpringMVC程序
    • 请求
      • @RequestMapping
      • 传递单参
      • 传递多参
      • 传递对象
      • 传递数组和集合
      • 传递JSON数据
      • @RequestParam
      • @PathVariable
      • @RequestPart
      • Cookie/Session
      • 获取Header
    • 响应
      • 返回静态页面
      • @ResponseBody
      • 返回HTML代码⽚段
      • 返回JSON
      • 设置状态码
      • 设置Header
      • 设置Content-Type
      • 设置响应编码
      • 设置其他Header
      • 设置响应编码
      • 设置其他Header

SpringMVC基础

SpringWebMVC是基于ServletAPI构建的原始Web框架,从⼀开始就包含在Spring框架中。

MVC理论基础

MVC是ModelViewController的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分

image-20231114162033705

  1. View(视图)指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源
  2. Model(模型)是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分
  3. Controller(控制器)可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图,⽤来连接视图和模型

Spring在实现MVC时,也结合⾃⾝项⽬的特点,做了⼀些改变:

image-20231114162345211

学习SpringMVC重点也就是学习如何通过浏览器和⽤⼾程序进⾏交互

主要分以下三个⽅⾯:

  1. 建⽴连接:将⽤⼾/浏览器和Java程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring程序

  2. 请求:⽤⼾请求的时候会带⼀些参数,在程序中要想办法获取到参数,所以请求这块主要是获取参数的功能

  3. 响应:执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤⼾,也就是响应

第一个SpringMVC程序

在SpringMVC中使⽤ @RequestMapping 来实现URL路由映射

创建⼀个UserController类:

@RestController
public class HelloController {
    @ResponseBody
    @RequestMapping("/")
    public String hello() {
        return "Hello,world";
    }
}

效果:

image-20231116164547448

请求

@RequestMapping

@RequestMapping 是⽤来注册接⼝的路由映射的

当⽤⼾访问⼀个URL时,将⽤⼾的请求对应到程序中某个类的某个⽅法的过程就叫路由映射

@RequestMapping即可修饰类,也可以修饰⽅法:

  1. @RequestMapping标识⼀个类:设置映射请求的请求路径的初始信息
  2. @RequestMapping标识⼀个⽅法:设置映射请求请求路径的具体信息
  3. 当修饰类和⽅法时,访问的地址是类路径+⽅法路径

注意:

  1. @RequestMapping 的URL路径也可以是多层路径
  2. @RequestMapping的URL路径最前⾯加不加 / (斜杠)都可以,Spring程序启动时,如果前⾯没有加会拼接上 /
  3. @RequestMapping 既⽀持Get请求,⼜⽀持Post请求,也⽀持其他的请求⽅式

指定GET/POST⽅法类型:

@RequestMapping(value = "/getRequest",method= RequestMethod.GET)
@RequestMapping(value = "/postRequest",method= RequestMethod.POST)

传递单参

接收单个参数,在SpringMVC中直接⽤⽅法中的参数就可以

@RestController
public class HelloController {
    @ResponseBody
    @RequestMapping("/")
    public String hello(String name) {
        return "Hello,world"+name;
    }
}

image-20231116171548864

注意:

  1. 使⽤基本类型来接收参数时,参数必须传(除boolean类型),否则会报500错误;类型不匹配时,会报400错误
  2. 对于包装类型,如果不传对应参数,Spring接收到的数据则为null
  3. 对于参数可能为空的数据,建议使⽤包装类型

传递多参

和接收单个参数⼀样,直接使⽤⽅法的参数接收即可

@RestController
public class HelloController {
    @ResponseBody
    @RequestMapping("/")
    public String hello(String name,int age) {
        return "Hello,world"+name+age;
    }
}

image-20231116172003297

注意:

前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果

传递对象

如果参数⽐较多时,⽅法声明就需要有很多形参,并且后续每次新增⼀个参数,也需要修改⽅法声明,这样不利于代码的维护
可以将这些参数封装为⼀个对象,SpringMVC可以⾃动实现对象参数的赋值

@Data
public class Person {
    String name;
    String sex;
    int age;
}
@RestController
public class HelloController {
    @ResponseBody
    @RequestMapping("/")
    public String hello(Person person) {
        return "Hello,world person:"+ person.getName()+person.getAge()+person.getSex();
    }
}

image-20231116172637747

注意:

Spring会根据参数名称⾃动绑定到对象的各个属性上,如果某个属性未传递,则赋值为null(基本类型则赋值为默认初识值,⽐如int类型的属性,会被赋值为0)

传递数组和集合

SpringMVC可以⾃动绑定数组参数的赋值

@RequestMapping("/m2")
public String m2(String[] str) {
    return "Hello,world str:"+ Arrays.toString(str);
}

image-20231116190946583

集合参数:和数组类似,需要使⽤ @RequestParam 绑定参数关系

默认情况下,请求中参数名相同的多个值,是封装到数组;如果要封装到集合,要使⽤@RequestParam 绑定参数关系

@RequestMapping("/m3")
public String m3(@RequestParam List<String> str) {
    return "Hello,world str:"+ str;
}

传递JSON数据

JSON的语法:

  1. 数据在 键值对(Key/Value) 中
  2. 数据由逗号 , 分隔
  3. 对象⽤ {} 表⽰
  4. 数组⽤ [] 表⽰
  5. 值可以为对象,也可以为数组,数组中可以包含多个对象

JSON优点:

  1. 简单易⽤:语法简单,易于理解和编写,可以快速地进⾏数据交换
  2. 跨平台⽀持:JSON可以被多种编程语⾔解析和⽣成,可以在不同的平台和语⾔之间进⾏数据交换和传输
  3. 轻量级:相较于XML格式,JSON数据格式更加轻量级,传输数据时占⽤带宽较⼩,可以提⾼数据传输速度
  4. 易于扩展:JSON的数据结构灵活,⽀持嵌套对象和数组等复杂的数据结构,便于扩展和使⽤
  5. 安全性:JSON数据格式是⼀种纯⽂本格式,不包含可执⾏代码,不会执⾏恶意代码,因此具有较⾼的安全性

基于以上特点,JSON在Web应⽤程序中被⼴泛使⽤,如前后端数据交互、API接⼝数据传输等

接收JSON对象,需要使⽤ @RequestBody 注解:

@RequestMapping("/m4")
public String m4(@RequestBody Person person) {
    return "Hello,world person:"+ person;
}

image-20231116195517241

@RequestParam

前端传递的参数key和我们后端接收的key可以不⼀致,可以使⽤ @RequestParam 来重命名前后端的参数值,进行构建映射关系

@ResponseBody
@RequestMapping("/m1")
public String m1(@RequestParam("name") String str) {
    return "Hello,world name:"+ str;
}

注意:

  1. 使⽤ @RequestParam 进⾏参数重命名时,请求参数只能和 @RequestParam 声明的名称⼀致,才能进⾏参数绑定和赋值
  2. 使⽤ @RequestParam 进⾏参数重命名时,参数就变成了必传参数

分析注解:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")//起别名
    String name() default "";

    boolean required() default true;//默认开启必传

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";//默认数值
}

设置非必传参数:

@RequestMapping("/m1")
public String m1(@RequestParam(value = "name",required = false) String str) {
    return "Hello,world name:"+ str;
}

@PathVariable

pathvariable:路径变量
和字⾯表达的意思⼀样,这个注解主要作⽤在请求URL路径上的数据绑定

@RequestMapping("/m5/{name}/{id}")
public String m5(@PathVariable Integer id, @PathVariable("name") String username) {
    return "Hello,world person:"+ id+username;
}

image-20231116195916263

如果⽅法参数名称和需要绑定的URL中的变量名称⼀致时,可以简写,不⽤给@PathVariable的属性赋值,否则需要@PathVariable的属性value赋值

@RequestPart

上传⽂件使用@RequestPart 注解

@RequestMapping("/m6")
public String m6(@RequestPart MultipartFile file) throws IOException {
    String fileName = file.getOriginalFilename();
    file.transferTo(new File("C:\\Users\\HP\\Desktop\\"+fileName));
    return "接收文件名称:"+fileName;
}

image-20231116202352915

Cookie/Session

Cookie和Session的区别:

  1. Cookie是客⼾端保存⽤⼾信息的⼀种机制;Session是服务器端保存⽤⼾信息的⼀种机制
  2. Cookie和Session之间主要是通过SessionId关联起来的;SessionId是Cookie和Session之间的桥梁
  3. Cookie和Session经常会在⼀起配合使⽤,但是不是必须配合
    ◦ 完全可以⽤Cookie来保存⼀些数据在客⼾端这些数据不⼀定是⽤⼾⾝份信息,也不⼀定是SessionId
    ◦ Session中的sessionId也不需要⾮得通过Cookie/Set-Cookie传递,⽐如通过URL传递

传统获取Cookie:

@RequestMapping("/m8")
public String m8(HttpServletRequest request, HttpServletResponse response) {
    Cookie[] cookies = request.getCookies();
    StringBuilder builder = new StringBuilder();
    if(cookies!=null) {
        for (Cookie ck:cookies) {
            builder.append(ck.getName()+":"+ck.getValue());
        }
    }
    return "Cookie:"+builder;
}

简洁获取Cookie:

@RequestMapping("/m8")
public String m9(@CookieValue("test") String test) {
    return "Cookie:"+test;
}

获取Session:

Session是服务器端的机制,我们需要先存储,才能再获取;Session也是基于HttpServletRequest来存储和获取的

@RequestMapping("/m9")
public String m9(HttpServletRequest request) {
    HttpSession session = request.getSession();
    if(session!=null) {
        session.setAttribute("test","hello");
    }
    return "session set";
}
@RequestMapping("/m10")
public String m10(HttpSession session) {
    return "session:"+session.getAttribute("test");
}

image-20231116211419448

说明:

  1. HttpSession getSession(boolean create):参数如果为true,则当不存在会话时新建会话;参数如果为false,则当不存在会话时返回null
  2. HttpSession getSession():和getSession(true)含义⼀样,默认值为true
  3. void setAttribute(Stringname,Objectvalue):使⽤指定的名称绑定⼀个对象到该session会话
  4. ObjectgetAttribute(Stringname):返回在该session会话中具有指定名称的对象,如果没有指定名称的对象,则返回null

简洁获取Session:

@RequestMapping("/m11")
public String m11(@SessionAttribute(value = "username",required = false) String name) {//获取指定key
    return "session:"+name;
}
public String m10(HttpSession session) {
    return "session:"+session.getAttribute("test");
}

获取Header

获取Header也是从 HttpServletRequest 中获取

@RequestMapping("/param10")
public String param10(HttpServletRequest request, HttpServletResponse response)
    String userAgent = request.getHeader("User-Agent");
	return name + ":"+userAgent;
}
@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
	return "userAgent:"+userAgent;
}

响应

Http响应结果可以是数据,也可以是静态⻚⾯,也可以针对响应设置状态码,Header信息等

返回静态页面

@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        //返回index.html
        return "/index.html";
    }
}

@RestController = @Controller + @ResponseBody

@Controller :定义⼀个控制器,Spring框架启动时加载,把这个对象交给Spring管理

@ResponseBody :定义返回的数据格式为⾮视图,返回⼀个text/html信息

如果想返回视图的话,只需要把 @ResponseBody 去掉就可以了,也就是 @Controller

@ResponseBody

@ResponseBody 表⽰返回数据

@ResponseBody 既是类注解,⼜是⽅法注解:

  1. 如果作⽤在类上,表⽰该类的所有⽅法,返回的都是数据,如果作⽤在⽅法上,表⽰该⽅法返回的是数据
  2. 如果类上有 @RestController 注解时:表⽰所有的⽅法上添加了 @ResponseBody 注解

返回HTML代码⽚段

后端返回数据时,如果数据中有HTML代码,也会被浏览器解析

响应中的Content-Type常⻅取值有以下⼏种:

  1. text/html:body数据格式是HTML
  2. text/css:body数据格式是CSS
  3. application/javascript:body数据格式是JavaScript
  4. application/json:body数据格式是JSON

如果请求的是js⽂件,SpringMVC会⾃动设置Content-Type为 application/javascript

如果请求的是css⽂件,SpringMVC会⾃动设置Content-Type为 text/css

返回JSON

SpringMVC也可以返回JSON,后端⽅法返回结果为对象

@RequestMapping("/returnJson")
@ResponseBody
public HashMap<String, String> returnJson() {
    HashMap<String, String> map = new HashMap<>();
    map.put("Java", "Java Value");
    map.put("MySQL", "MySQL Value");
    map.put("Redis", "Redis Value");
    return map;
}

image-20231116213323566

设置状态码

SpringMVC会根据我们⽅法的返回结果⾃动设置响应状态码,程序员也可以⼿动指定状态码

通过SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

@RequestMapping(value = "/setStatus")
@ResponseBody
public String setStatus(HttpServletResponse response) {
    response.setStatus(401);
    return "设置状态码成功";
}

状态码不影响⻚⾯的展⽰

设置Header

Http响应报头也会向客⼾端传递⼀些附加信息,⽐如服务程序的名称,请求的资源已移动到新地址等,如:Content-Type,Local等

通过 @RequestMapping 注解的属性来实现

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";
    @AliasFor("path")
    String[] value() default {};
    @AliasFor("value")
    String[] path() default {};
    RequestMethod[] method() default {};
    String[] params() default {};
    String[] headers() default {};
    String[] consumes() default {};
	String[] produces() default {};
}

说明:

  1. value:指定映射的URL
  2. method:指定请求的method类型,如GET,POST等
  3. consumes:指定处理请求(request)的提交内容类型(Content-Type),例如application/json,text/html;
  4. produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
  5. Params:指定request中必须包含某些参数值时,才让该⽅法处理
  6. headers:指定request中必须包含某些指定的header值,才能让该⽅法处理请求

设置Content-Type

通过设置produces属性的值,设置响应的报头Content-Type

@RequestMapping(value = "/returnJson2",produces = "application/json")
@ResponseBody
public String returnJson2() {
	return "{\"success\":true}";
}

如果不设置produces,⽅法返回结果为String时,SpringMVC默认返回类型,是text/html

设置响应编码

@RequestMapping(value = "/returnJson2",produces = "application/json;charset=ut
@ResponseBody
public String returnJson2() {
    return "{\"success\":true}";
}

设置其他Header

使⽤SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
response.setHeader("MyHeader","MyHeaderValue");
    return "设置Header成功";
}

设置⼀个带有给定的名称和值的header,如果name已经存在,则覆盖旧的值
返回类型,是text/html

设置响应编码

@RequestMapping(value = "/returnJson2",produces = "application/json;charset=ut
@ResponseBody
public String returnJson2() {
    return "{\"success\":true}";
}

设置其他Header

使⽤SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
response.setHeader("MyHeader","MyHeaderValue");
    return "设置Header成功";
}

设置⼀个带有给定的名称和值的header,如果name已经存在,则覆盖旧的值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/160997.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity3D 解决相机拉高之后物体阴影消失

在Edit-Project Settings-Quality中找到Shadow Distance&#xff0c;将其调大即可

FreeRtos 任务切换深入分析

一、背景知识&#xff1a; 1、任务切换包含三个基本流程&#xff1a;保护现场、更新TCB、恢复现场并跳转 2、freertos的任务切换是在xPortPendSVHandler 中断函数中完成的 3、中断函数在调用之前&#xff0c;硬件已经保存了r0,r1,r2,r3,r12,r14(LR),r15(pc)&#xff0c;恢复…

山西电力市场日前价格预测【2023-11-18】

1.日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-18&#xff09;山西电力市场全天平均日前电价为202.44元/MWh。其中&#xff0c;最高日前电价为346.71元/MWh&#xff0c;预计出现在18:00。最低日前电价为0.00元/MWh&#xff0c;预计…

Lesson 03 C/C++内存管理

C&#xff1a;渴望力量吗&#xff0c;少年&#xff1f; 文章目录 一、C内存管理方式1. new/delete操作内置类型2. new和delete操作自定义类型 二、operator new与operator delete函数三、new和delete的实现原理1. 内置类型2. 自定义类型 四、内存泄漏1. 什么是内存泄漏2. 内存泄…

基于Python实现大型家用电器和电子产品在线商店购买数据分析【500010098】

导入模块 import pandas as pd import numpy as np import matplotlib.pyplot as plt获取数据 df pd.read_csv( r"./data/kz.csv",sep,)数据描述 该数据包含2020年4月至2020年11月从大型家用电器和电子产品在线商店购买的数据。 数据说明 event_time&#xff1a…

[最新榜单] 智能手机数据恢复的 10 款最佳应用

当手机上的数据消失时&#xff0c;这让您感到非常难过。 由于事故而突然丢失重要的聊天记忆、照片和其他您想保留的东西的悲伤。 如果它没有被淹没&#xff0c;您可以使用数据恢复应用程序修复它。 在本文中&#xff0c;我们将解释一些有用的数据恢复应用程序。 数据恢复应用…

「Verilog学习笔记」数据选择器实现逻辑电路

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 将变量A、B接入4选1数据选择器选择输入端S0 S1。将变量C分配在数据输入端。从表中可以看出输出L与变量C的关系。 当AB00时选通D0而此时L0&#xff0c;所以数据端D0接0…

PyTorch 实战之水果分类

当我们试图提高神经网络的准确性时&#xff0c;经常会遇到过拟合训练数据的情况。当我们运行测试数据的模型时&#xff0c;这会导致一个糟糕的预测。因此&#xff0c;我采取了一个数据集&#xff0c;并应用这些技术&#xff0c;不仅提高准确性&#xff0c;而且还处理过拟合的问…

AI技术:分享8个非常实用的AI绘画网站

目录 1、Midjourney 2、Stable Diffusion Omline 3、Microsoft Designer 4、Craiyon 5、NightCafe Studio 6、Wombo 7、Dalle-2 8、Avatar AI 1、Midjourney 特点&#xff1a;业内标杆&#xff0c;效果最强大 Midjourney是基于diffusion的AI图画艺术生成器。生成图片不…

OpenAI GPT-4 Turbo发布:开创AI新时代

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; IT杂谈 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. GPT-4 Turbo的突破1.1上下文长度和控制手段的加强&#xff1a;1.2多模态支持&#xff1a…

vb.net U盘或移动硬盘 插入 自动(静默)复制指定格式文件

U盘或移动硬盘 插入 自动复制指定格式文件至系统盘符 开发语言&#xff1a;vb.net 重要申明&#xff1a;该程序只是防止本人不在电脑旁时&#xff0c;别人偷偷copy你的电脑文件&#xff0c;让他偷鸡成了也要蚀把米。严禁从事黑客或违反道德等不良行为&#xff0c;故而不发布程…

通信原理板块——奇偶监督码、方阵码、恒比码、正反码

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 1、奇偶监督码(parity check) 奇偶…

微信小程序开发---实现文件上传和下载

在开发小程序的过程中&#xff0c;我们难免会遇到使用小程序对后端发送文件&#xff1b;或者接收后端的文件&#xff0c;本文章将手把手带你简单高效实现微信小程序的文件上传下载功能 前期准备 由于目前小程序保护用户个人隐私力度加大 &#xff0c;因此我们要想实现文件上传…

uniapp优化h5项目-摇树优化,gzip压缩和删除console.log

1.摇树优化 勾选摇树优化,打包删除死代码 2.gzip压缩和删除console.log 安装插件webpack和compression-webpack-plugin webpack插件 npm install webpack4.46.0 --save-devcompression-webpack-plugin插件 npm install compression-webpack-plugin6.1.1 --save-devconst Com…

为什么C++标准库中atomic shared_ptr不是lockfree实现?

为什么C标准库中atomic shared_ptr不是lockfree实现&#xff1f; 把 shared_ptr 做成 lock_free&#xff0c;应该是没有技术上的可行性。shared_ptr 比一个指针要大不少&#xff1a;最近很多小伙伴找我&#xff0c;说想要一些C的资料&#xff0c;然后我根据自己从业十年经验&am…

CVE-2021-42287CVE-2021-42278 域内提权

倘见玉皇先跪奏&#xff1a;他生永不落红尘 本文首发于先知社区&#xff0c;原创作者即是本人 前言 网络安全技术学习&#xff0c;承认⾃⼰的弱点不是丑事。只有对原理了然于⼼&#xff0c;才能突破更多的限制。拥有快速学习能力的白帽子&#xff0c;是不能有短板的&#xf…

四、hdfs文件系统基础操作-保姆级教程

1、启动Hadoop集群 想要使用hdfs文件系统&#xff0c;就先要启动Hadoop集群。 启动集群: start-dfs.sh 关闭集群: stop-dfs.sh 2、文件系统构成 &#xff08;1&#xff09;基础介绍 其实hdfs作为分布式存储的文件系统&#xff0c;其构成和Linux文件系统构成差不多一…

monaco-editor 简单使用

一. 文件调用示例 1. 安装package包 官方文档 "monaco-editor": "^0.28.1", "monaco-editor-webpack-plugin": "^4.2.0", Copy 请注意安装包的版本号 monaco-editor-webpack-pluginmonaco-editor7.*.*> 0.31.06.*.*0.30.*5.*.*…

STM32/N32G455国民科技芯片驱动DS1302时钟---笔记

这次来分享一下DS1302时钟IC&#xff0c;之前听说过这个IC&#xff0c;但是一直没搞过&#xff0c;用了半天时间就明白了原理和驱动&#xff0c;说明还是很简单的。 注&#xff1a;首先来区分一下DS1302和RTC时钟有什么不同&#xff0c;为什么不直接用RTC呢&#xff1f; RTC不…

基于社会群体算法优化概率神经网络PNN的分类预测 - 附代码

基于社会群体算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于社会群体算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于社会群体优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…