SpringMVC ——(1)
1.SpringMVC请求流程
1.1 SpringMVC请求处理流程分析
Spring MVC框架也是⼀个基于请求驱动的Web框架,并且使⽤了前端控制器模式(是⽤来提供⼀个集中的请求处理机制,所有的请求都将由⼀个单⼀的处理程序处理来进⾏设计,再根据请求映射规则分发给相应的⻚⾯控制器(动作/处理器)进⾏处理。⾸先让我们整体看⼀下Spring MVC处理请求的流程:
1.⾸先⽤户发送请求,请求被SpringMvc前端控制器(DispatherServlet)捕获;
2.前端控制器(DispatherServlet)对请求URL解析获取请求URI,根据URI, 调⽤HandlerMapping;
3.前端控制器(DispatherServlet)获得返回的HandlerExecutionChain(包括Handler对象以及Handler对象对应的拦截器);
4.DispatcherServlet 根据获得的HandlerExecutionChain,选择⼀个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter 后,此时将开始执⾏拦截器的preHandler(...)⽅法);
5.HandlerAdapter根据请求的Handler适配并执⾏对应的Handler;HandlerAdapter(提取Request中的模型数据,填充Handler⼊参,开 始执⾏Handler(Controller)。 在填充Handler的⼊参过程中,根据配置,Spring将做⼀些额外的工作:
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成⼀个对象,将对象转换为指定的响应信息。
数据转换:对请求消息进⾏数据转换。如String转换成Integer、Double等数据格式化:
数据格式化。 如将字符串转换成格式化数字或格式化⽇期等
数据验证: 验证数据的有效性(⻓度、格式等),验证结果存储到BindingResult或Error中)
6.Handler执⾏完毕,返回⼀个ModelAndView(即模型和视图)给HandlerAdaptor
7.HandlerAdaptor适配器将执⾏结果ModelAndView返回给前端控制器。
8.前端控制器接收到ModelAndView后,请求对应的视图解析器。
9.视图解析器解析ModelAndView后返回对应View;
10.渲染视图并返回渲染后的视图给前端控制器。
11.最终前端控制器将渲染后的⻚⾯响应给⽤户或客户端
2.SpringMVC环境搭建
2.1开发环境
Idea + Maven + Jdk1.8 + Jetty
2.2. 新建 Maven webApp
Idea 下创建 springmvc01 ⼯程
2.3 pom.xml
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties>
<dependencies><!-- spring web --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.2.4.RELEASE</version></dependency><!-- spring mvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.4.RELEASE</version></dependency><!-- web servlet --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version></dependency></dependencies><build><finalName>SpringMVC1</finalName>
<plugins><!-- 编译环境插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><!-- jetty插件 --><plugin><groupId>org.eclipse.jetty</groupId><artifactId>jetty-maven-plugin</artifactId><version>9.4.27.v20200227</version><configuration><scanIntervalSeconds>10</scanIntervalSeconds><!-- 设置端⼝ --><httpConnector><port>8080</port></httpConnector><!-- 设置项⽬路径 --><webAppConfig><contextPath>/springmvc01</contextPath></webAppConfig></configuration></plugin></plugins></build>
2.4 配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!-- 编码过滤 utf-8 --><filter><description>char encoding filter</description><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- servlet请求分发器 --><servlet><servlet-name>springMvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:servlet-context.xml</param-value></init-param><!-- 表示启动容器时初始化该Servlet --><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springMvc</servlet-name><!-- 这是拦截请求, "/"代表拦截所有请求,"*.do"拦截所有.do请求 --><!-- <url-pattern>/</url-pattern> --><url-pattern>*.do</url-pattern></servlet-mapping>
</web-app>
2.4.1 servlet-context.xml配置
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启扫描器 --><context:component-scan base-package="org.example.springmvc.controller"/><!-- 使⽤默认的 Servlet 来响应静态⽂件 --><mvc:default-servlet-handler/><!-- 开启注解驱动--><mvc:annotation-driven/><!-- 配置视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"id="internalResourceViewResolver"><!-- 前缀:在WEB-INF⽬录下的jsp⽬录下 --><property name="prefix" value="/WEB-INF/jsp/"/><!-- 后缀:以.jsp结尾的资源 --><property name="suffix" value=".jsp"/></bean>
</beans>
2.4.2 页面控制器的编写
package org.example.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class HelloController {
/*** 请求映射地址 /hello.do* @return*/@RequestMapping("/hello")public ModelAndView hello(){ModelAndView mv=new ModelAndView();mv.addObject("hello", "hello spring mvc");mv.setViewName("hello");return mv;}
}
2.4.3 添加视图页面
在 WEB-INF 下新建 jsp ⽂件夹 ,并在⽂件夹下新建 hello.jsp
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%String path = request.getContextPath();String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML>
<html>
<head><base href="<%=basePath %>"><title>My JSP 'hello.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page">
</head>
<body>
<!-- el表达式接收参数值 -->
${hello}
</body>
</html>
2.4.4 启动jetty服务器
2.4.5 页面结果
访问地址 http://localhost:8080/springmvc01/hello.do
3.URL地址映射配置
3.1 @RequestMapping
* URL地址映射配置 * @RequestMappping("路径") * 注解可以声明在类级别或方法级别。如果注解设置在类级别,则表示将请求路径与控制器绑定;如果将注解设置在方法级别,则表示请求路径与方法绑定 * 1.类级别 * 2.方法级别 * 3.类级别+方法级别 * 注:如果在类上设置了@RequestMapping注解,则访问时需要将类路径当做方法路径的父路径。即 类路径/方法路径
3.1.1 映射单个URL
@RequestMapping("") 或 @RequestMapping(value="")
/*** @RequestMapping 声明在⽅法上⾯,映射单个 URL* 访问地址:(如果有类路径需要写在⽅法路径前⾯)* http://ip:port/springmvc01/test01* @return*/@RequestMapping("/test01")
// @RequestMapping(value = "/test01")public ModelAndView test01(){ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("hello","test01");modelAndView.setViewName("hello");return modelAndView;}/*** 路径开头是否加 斜杠"/" 均可* @RequestMapping("/请求路径") 与 @RequestMapping("请求路径")均可* 建议加上,如:@RequestMapping("/test02")* 访问地址:(如果有类路径需要写在⽅法路径前⾯)* http://ip:port/springmvc01/test02* @return*/@RequestMapping("test02")public ModelAndView test02(){ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("hello","test02");modelAndView.setViewName("hello");return modelAndView;}
3.1.2 映射多个URL
@RequestMapping({"",""}) 或 @RequestMapping(value={"",""})
/*** @RequestMapping 声明在⽅法上⾯,映射多个 URL* ⽀持⼀个⽅法绑定多个 url 的操作* 访问地址:(如果有类路径需要写在⽅法路径前⾯)* http://ip:port/springmvc01/test03_01* http://ip:port/springmvc01/test03_02* @return*/@RequestMapping({"/test03_01","/test03_02"})
// @RequestMapping(value = {"/test03_01","/test03_02"})public ModelAndView test03() {ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("hello", "test03");modelAndView.setViewName("hello");return modelAndView;}
3.1.3 映射URL在控制器上
@Controller
@RequestMapping("/url")
public class UrlController {/*** @RequestMapping 声明在类上⾯,类中的的⽅法都是以该地址作为⽗路径* 声明级别:* 类级别 + ⽅法级别 (/类路径/⽅法路径)* 访问地址:* http://ip:port/springmvc01/url/test04* @return*/@RequestMapping("/test04")public ModelAndView test04(){ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("hello","test04");modelAndView.setViewName("hello");return modelAndView;}
}
3.1.4 设置URL映射的请求方式
/*** 设置请求⽅式* 通过 method 属性设置⽅法⽀持的请求⽅式,默认 GET请求和 POST等请求都⽀持。* 设置了请求⽅式,则只能按照指定的请求⽅式请求。* 访问地址:(只能使⽤POST请求访问)* http://ip:port/springmvc01/url/test05* @return*/
@RequestMapping(value = "/test05",method = RequestMethod.POST)
public ModelAndView test05(){ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("hello","test05");modelAndView.setViewName("hello");return modelAndView;
}
3.1.5 通过参数名称映射URL
/*** 通过参数名称访问* 通过参数的形式访问* 访问地址:* http://ip:port/springmvc01/url?test06* @return*/
@RequestMapping(params = "test06")
public ModelAndView test06(){ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("hello","test06");modelAndView.setViewName("hello");return modelAndView;
}
4.参数绑定
4.1 基本数据类型
访问地址:http://localhost:8080/springmvc01/data01?age=18&money=500 (问号后面为参数)
/*** 基本类型数据绑定* 参数值必须存在。如果没有指定参数值,也没有设置参数默认值,则会报500异常。* @param age* @param money*/
@RequestMapping("data01")
public void data01(int age, double money){System.out.println("age:" + age + ", money:" + money);
}
/*** 基本类型数据绑定* 通过注解 @RequestParam 标记⼀个形参为请求参数。(注解声明在形参的前⾯)* 可以通过注解的属性设置相关内容* 设置参数的默认值 defaultValue* @param age* @param money*/
@RequestMapping("data02")
public void data02(@RequestParam(defaultValue = "18") int age,
@RequestParam(defaultValue = "10.0") double money){System.out.println("age:" + age + ", money:" + money);
}
/*** 基本类型数据绑定* 通过注解 @RequestParam 标记⼀个形参为请求参数。(注解声明在形参的前⾯)* 可以通过注解的属性设置相关内容* 设置参数的参数名(别名) name* @param age* @param money*/
@RequestMapping("data03")
public void data03(@RequestParam(defaultValue = "18", name = "userAge") int age,
@RequestParam(defaultValue = "10.0", name = "userMoney") double money){System.out.println("age:" + age + ", money:" + money);
}
4.2 包装类型
/*** 包装类型数据绑定 (如果数据是基本类型,建议使⽤包装类型)* 客户端请求参数名与⽅法形参名保持⼀致,默认参数值为null* 可以通过 @RequestParam 的name属性设置参数的别名,defaultValue属性设置参数默认值* @param age* @param money*/
@RequestMapping("data05")
public void data05(Integer age, Double money){System.out.println("age:" + age + ", money:" + money);
}
4.3 字符串类型
/*** 字符串数据绑定* 客户端请求参数名与⽅法形参名保持⼀致,默认参数值为null* 可以通过 @RequestParam 的name属性设置参数的别名,defaultValue属性设置参数默认值* @param userName* @param userPwd*/
@RequestMapping("data04")
public void data04(String userName, String userPwd){System.out.println("userName:" + userName + ", userPwd:" + userPwd);
}
4.4 数组类型
/*** 数组类型数据绑定* 客户端传参形式:ids=1&ids=2&ids=3* @param ids*/
@RequestMapping("/data06")
public void data06(String[] ids){for(String id : ids){System.out.println(id + "---");}
}
4.5 JavaBean类型
/*** JavaBean 数据绑定* 客户端请求的参数名与JavaBean对象的属性字段名保持⼀致* @param user*/
@RequestMapping("/data07")
public void data07(User user) {System.out.println(user);
}
User.java
package com.xxxx.springmvc.po;
public class User {private int id;private String userName;private String userPwd;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserPwd() {return userPwd;}public void setUserPwd(String userPwd) {this.userPwd = userPwd;}@Overridepublic String toString() {return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + "]";}
}
4.6 List类型
此时 User 实体需要定义对应 list 属性。(对于集合的参数绑定,⼀般需要使⽤ JavaBean 对象进⾏包装)
public class User {private int id;private String userName;private String userPwd;
private List<Phone> phones = new ArrayList<Phone>();public List<Phone> getPhones() {return phones;}public void setPhones(List<Phone> phones) {this.phones = phones;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserPwd() {return userPwd;}public void setUserPwd(String userPwd) {this.userPwd = userPwd;}@Overridepublic String toString() {return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + ", phones=" + phones + "]";}
}
Phone实体
public class Phone {private String num;public String getNum() {return num;}public void setNum(String num) {this.num = num;}@Overridepublic String toString() {return "Phone [num=" + num + "]";}}
Jsp ⻚⾯定义
<form action="data08" method="post"><input name="phones[0].num" value="123456" /><input name="phones[1].num" value="4576" /><button type="submit"> 提交</button> </form>
Controller ⽅法
@RequestMapping("/data08")
public void data08(User user){System.out.println(user);
}
4.7 Set类型
Set 和 List 类似,也需要绑定在对象上,⽽不能直接写在 Controller ⽅法的参数中。但是,绑定Set数
据时,必须先在Set对象中add相应的数量的模型对象。
public class User {private int id;private String userName;private String userPwd;
private Set<Phone> phones = new HashSet<Phone>();
public User() {phones.add(new Phone());phones.add(new Phone());phones.add(new Phone());}/*public List<Phone> getPhones() {return phones;}public void setPhones(List<Phone> phones) {this.phones = phones;}*/public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserPwd() {return userPwd;}public void setUserPwd(String userPwd) {this.userPwd = userPwd;}public Set<Phone> getPhones() {return phones;}public void setPhones(Set<Phone> phones) {this.phones = phones;}
}
Controller ⽅法
@RequestMapping("/data09")
public void data09(User user){System.out.println(user);
}
表单⻚⾯
<form action="data09" method="post"><input name="phones[0].num" value="123456" /><input name="phones[1].num" value="4576" /><input name="phones[2].num" value="4576" /><button type="submit"> 提交</button> </form>
4.8 Map类型
Map最为灵活,它也需要绑定在对象上,⽽不能直接写在Controller⽅法的参数中。
public class User {private int id;private String userName;private String userPwd;
private Set<Phone> phones=new HashSet<Phone>();
private Map<String, Phone> map=new HashMap<String, Phone>();
// private List<Phone> phones=new ArrayList<Phone>();
public User() {phones.add(new Phone());phones.add(new Phone());phones.add(new Phone());}/*public List<Phone> getPhones() {return phones;}public void setPhones(List<Phone> phones) {this.phones = phones;}*/public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserPwd() {return userPwd;}public void setUserPwd(String userPwd) {this.userPwd = userPwd;}public Set<Phone> getPhones() {return phones;}public void setPhones(Set<Phone> phones) {this.phones = phones;}public Map<String, Phone> getMap() {return map;}public void setMap(Map<String, Phone> map) {this.map = map;}
}
Controller ⽅法
@RequestMapping("/data10")
public void data10(User user){Set<Entry<String, Phone>> set = user.getMap().entrySet();for(Entry<String, Phone> entry:set){System.out.println(entry.getKey()+"--"+entry.getValue().getNum());}
}
表单页面
<form action="data10" method="post"><input name="map['1'].num" value="123456" /><input name="map['2'].num" value="4576" /><input name="map['3'].num" value="4576" /><button type="submit"> 提交</button> </form
5.请求转发与重定向
SpringMVC默认采⽤服务器内部转发的形式展示⻚⾯信息。同样也⽀持重定向⻚⾯。
5.1 重定向
重定向是发⼀个302的状态码给浏览器,浏览器⾃⼰去请求跳转的⽹⻚。地址栏会发⽣改变。
重定向以 redirect: 开头
/*** 重定向到JSP⻚⾯* @return*/
@RequestMapping(value="/view01")
public String view01(){return "redirect:view.jsp";
}
/*** 重定向到JSP⻚⾯* 传递参数* @return*/
@RequestMapping(value="/view02")
public String view02(){return "redirect:view.jsp?uname=zhangsan&upwd=123456";
}
/*** 重定向到JSP⻚⾯* 传递参数 (传递中⽂参数会出现乱码)* @return*/
@RequestMapping(value="/view03")
public String view03(){return "redirect:view.jsp?uname=张三&upwd=123456";
}
/*** 重定向到JSP⻚⾯* 传递参数 (通过 RedirectAttributes 对象设置重定向参数,避免中⽂乱码问题)* @param redirectAttributes* @return*/
@RequestMapping(value="/view04")
public String view04(RedirectAttributes redirectAttributes){redirectAttributes.addAttribute("uname","张三");redirectAttributes.addAttribute("upwd","123456");return "redirect:view.jsp";
}
/*** 重定向到JSP⻚⾯* 返回 ModelAndView 对象* @param modelAndView* @return*/
@RequestMapping(value="/view06")
public ModelAndView view06(ModelAndView modelAndView){modelAndView.addObject("uname","李四");modelAndView.addObject("upwd","123321");modelAndView.setViewName("redirect:view.jsp");return modelAndView;
}
/*** 重定向到Controller* 返回 ModelAndView 对象* @param modelAndView* @return*/
@RequestMapping(value="/view07")
public ModelAndView view07(ModelAndView modelAndView){modelAndView.addObject("uname","admin");modelAndView.setViewName("redirect:test01");return modelAndView;
}
⻚⾯中获取参数值
${param.参数名}
5.2 请求转发
请求转发,直接调⽤跳转的⻚⾯,让它返回。对于浏览器来说,它⽆法感觉服务器有没有forward。地址栏不发⽣改变。可以获取请求域中的数据。
请求转发以 forward: 开头
/*** 请求转发到JSP⻚⾯*/
@RequestMapping("/view08")
public String view08(){return "forward:view.jsp";
}
/*** 请求转发到JSP⻚⾯* 设置参数*/
@RequestMapping("/view09")
public String view09(){return "forward:view.jsp?uname=张三&upwd=123456";
}
/*** 请求转发到JSP⻚⾯* 设置请求域*/
@RequestMapping("/view10")
public String view10(Model model){model.addAttribute("uname","张三");return "forward:view.jsp";
}
/*** 请求转发到JSP⻚⾯ (默认)* 默认会去指定⽬录下找JSP⻚⾯ (配置⽂件中设置的)*/
@RequestMapping("/view11")
public String view11(){return "/../../view";
}
/*** 请求转发到 Controller* @return*/
@RequestMapping("/view12")
public ModelAndView view12(ModelAndView modelAndView){modelAndView.setViewName("forward:test01");return modelAndView;
}
/*** 请求转发到 Controller* 传递参数* @return*/
@RequestMapping("/view13")
public ModelAndView view13(ModelAndView modelAndView){modelAndView.setViewName("forward:test01?uname=admin");return modelAndView;
}
⻚⾯中获取数据
获取传递的参数:${param.参数名} 获取请求域的数据:${请求域中设置的名称}
6.JSON数据开发
6.1 基本概念
Json 在企业开发中已经作为通⽤的接⼝参数类型,在⻚⾯(客户端)解析很⽅便。SpringMVC 对于json 提供了良好的⽀持,这⾥需要修改相关配置,添加 json 数据⽀持功能。
6.1.1 @ResponseBody
该注解⽤于将 Controller 的⽅法返回的对象,通过适当的 HttpMessageConverter 转换为指定格式后,写⼊到 Response 对象的 body 数据区。
返回的数据不是 html 标签的⻚⾯,⽽是其他某种格式的数据时(如 json、xml 等)使⽤(通常⽤于ajax请求)。
6.1.2 @RequestBody
该注解⽤于读取 Request 请求的 body 部分数据,使⽤系统默认配置的 HttpMessageConverter 进⾏解析,然后把相应的数据绑定到要返回的对象上 ,再把 HttpMessageConverter 返回的对象数据绑定到controller 中⽅法的参数上。
6.2 使用配置
6.2.1 添加json相关坐标
pom.xml
<!-- 添加json 依赖jar包 --> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.10.0</version> </dependency> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.10.0</version> </dependency> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.10.0</version> </dependency>
6.2.2 修改配置⽂件
servlet-context.xml
<!-- mvc 请求映射 处理器与适配器配置 --> <mvc:annotation-driven><mvc:message-converters><bean class="org.springframework.http.converter.StringHttpMessageConverter" /><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /></mvc:message-converters> </mvc:annotation-driven>
6.2.3 注解使用
6.2.3.1 @ResponseBody
@Controller
@RequestMapping("/user")
public class UserController {/*** @ResponseBody 返回的是JOSN格式的数据,返回JavaBean对象* 注解设置在⽅法体上* @return*/@RequestMapping("queryUser01")@ResponseBodypublic User queryUser01(){User user = new User();user.setId(1);user.setUserName("zhangsan");user.setUserPwd("123456");// 返回的是user对象return user;}/*** @ResponseBody 返回的是JOSN格式的数据,返回JavaBean对象* 注解设置在⽅法返回对象前,修饰符之后* @return*/@RequestMapping("queryUser02")public @ResponseBody User queryUser02(){User user = new User();user.setId(2);user.setUserName("lisi");user.setUserPwd("123321");// 返回的是user对象return user;}
/*** @ResponseBody 返回的是JOSN格式的数据,返回集合* @return*/@RequestMapping("queryUser02")public @ResponseBody User queryUser02(){User user = new User();user.setId(2);user.setUserName("lisi");user.setUserPwd("123321");// 返回的是user对象return user;}
/*** @ResponseBody 返回的是JOSN格式的数据,返回集合* @return*/@RequestMapping("/queryUser03")@ResponseBodypublic List<User> queryUser03(){List<User> list = new ArrayList<>();User user01 = new User();user01.setId(1);user01.setUserName("zhangsan");user01.setUserPwd("123456");User user02 = new User();user02.setId(2);user02.setUserName("lisi");user02.setUserPwd("123321");list.add(user01);list.add(user02);// 返回的是user集合return list;}
}
6.2.3.2 @RequestBody
@RequestBody 注解常⽤来处理 content-type 不是默认的 application/x-www-form-urlcoded 类型的内容,⽐如说:application/json 或者是application/xml 等。⼀般情况下来说常⽤其来处理 application/json类型。@RequestBody接受的是⼀个 json 格式的字符串,⼀定是⼀个字符串。
通过 @RequestBody 可以将请求体中的 JSON 字符串绑定到相应的 bean 上,当然,也可以将其分别绑定到对应的字符串上。
/*** @RequestBody 规定请求的参数是JOSN格式的字符串* 注解设置在形参前⾯* @param user* @return*/
@RequestMapping("/getUser")
@ResponseBody
public User getUser(@RequestBody User user){System.out.println(user);return user;
}
相关文章:

SpringMVC ——(1)
1.SpringMVC请求流程 1.1 SpringMVC请求处理流程分析 Spring MVC框架也是⼀个基于请求驱动的Web框架,并且使⽤了前端控制器模式(是⽤来提供⼀个集中的请求处理机制,所有的请求都将由⼀个单⼀的处理程序处理来进⾏设计,再根据请求…...

嵌入式中防linux的通用MCU系统
大家好,今天分享一个仿linux分层架构实现的mcu通用系统,该项目的创建方便芯片级切换以及多产品线开发。 《一个基于分层架构实现的MCU通用系统》 项目整体框图 项目亮点 分层架构,清晰高效:usal_mcu采用仿Linux的分层架构设计,将系统划分为驱动层、系统层和应用层, 每…...

Windows电脑伪关机(快速启动模式),怎么真关机
Windows电脑在关机的时候,进入到一个伪关机的状态,也就是并没有真正的关机,但是在一些系统更新、变更了一些设置,进行重启等操作也会进入到真关机状态 这种一般是开启快速启动模式,开启了快速启动模式功能会在关机的时…...

远程修改ESXi 6.7管理IP地址
1.启用安全Shell(也就是EXSi可以被SSH访问的功能) 2.使用SecureCRT SSH2连接ESXi主机,现在使用dcui并没有任何反应,在Session标签栏右键点击Disconnect。 The time and date of this login have been sent to the system logs.WA…...

DICOM医学影象应用篇——多平面重建(MPR)在DICOM医学影像中的应用详解
目录 MPR(多平面重建)概述 基本原理 具体实现 代码详解 总结 MPR(多平面重建)概述 多平面重建(MPR, Multi-Planar Reconstruction)是一项用于从三维医学影像数据集中生成不同平面的二维切片的技术。通常应用于CT或MRI数据集,MPR可以帮助医…...

chromedriver.exe编译
使用例子参考官网 ChromeDriver 使用入门 | Chrome for Developers Chrome for Testing availability 注意:chromedriver版本要与chromium版本号对应。 如何编译chromedriver chrome\test\chromedriver\BUILD.gn 1、ninja -C out/debug chromedriver_server…...

CVPR和其他2024顶会论文阅读(资源整理【1】)
CVPR 2024论文阅读(资源整理【1】) 一、3d 重建与建模论文1-Deformable 3D Gaussians for High-Fidelity Monocular Dynamic Scene Reconstruction论文2- 4D Gaussian Splatting for Real-Time Dynamic Scene Rendering论文3-GaussianDreamer: Fast Generation from Text to …...

封闭式论文写作--全面掌握ChatGPT-4o的写作技能,掌握提示词使用技巧、文献检索与分析方法,帮助您选定研究方向,提炼学术论文题目
在当今学术研究中,科研人员在撰写论文时面临诸多挑战。首先是信息量的剧增,科研人员需要快速消化新知识,筛选相关信息并清晰表达。但论文写作不仅是信息的罗列,还需要条理清晰、逻辑严密、语言精准,特别是在竞争激烈的…...

ThinkPad X250在 FreeBSD xfce4下小红点不能用、触摸板不能用以及键盘上下左右变成其它键
某一天突然发现,键盘的上,变成了PrtSc键,每次按上,就调用一次抓屏....上下左右键盘都乱了。 找了很多方法,发现设置键盘,可以解决这个问题。但是在设置多次键盘后,发现ThinkPad X250的小红点不…...

PowerShell install 一键部署postgres17
postgres 前言 PostgreSQL 是一个功能强大的开源对象关系数据库系统,拥有超过 35 年的积极开发经验 这为其赢得了可靠性、功能稳健性和性能的良好声誉。 通过官方文档可以找到大量描述如何安装和使用 PostgreSQL 的信息。 开源社区提供了许多有用的地方来熟悉PostgreSQL, 了…...

k8s的数据库etcd报 etcdserver: mvcc: database space exceeded的处理办法
一.问题现象 公司的k8s集群的etcd配置是默认配置,其磁盘配置为2GB的配额,目前出现了数据写入失败的情况,报错Error: etcdserver: mvcc: database space exceeded。 二.处理思路 当etcd的磁盘使用达到2G后,可能会触发维护模式&am…...

MySQL——buffer poll
为什么要有buffer poll? 如果没有buffer poll,每次读取数据的时候都是从磁盘上读的,这样效率是很差的的。 所以有了提高效率的方式,就加上了一个缓存——buffer poll 所以,当我们读取数据的时候就有以下的方式 当读…...

使用GO--Swagger生成文档
概述 在前后端分离的项目中,后端配置swagger可以很好的帮助前端人员了解后端接口参数和数据传输。go-swagger 是一个功能全面且高性能的Go语言实现工具包,用于处理Swagger 2.0(即OpenAPI 2.0)规范。它提供了丰富的工具集&#x…...

Pac4j 学习笔记
随着互联网技术的飞速发展,网络安全问题日益凸显,企业信息安全与身份认证系统变得越来越重要,而且安全认证集成方案作为保障网络安全的重要一环,其研究与应用也至关重要。在这种背景下,Pac4j 作为一种流行的身份验证库…...

什么?RayLink远程控制软件支持企业IT应用!
在当今企业IT管理中,远程控制工具扮演着不可或缺的角色。设想一下,你的团队成员分散在全球各地,或者员工正在远程工作,这时电脑突然出现问题。如果IT支持团队能够利用远程控制软件,比如RayLink,迅速远程接入…...

LeetCode Hot100 51~60
图论51. 岛屿问题52. 腐烂的橘子53. 课程表54. 前缀树55. 全排列56. 子集57. 电话号码58. 组合总和59. 括号生成60. 单词搜索 图论 51. 岛屿问题 经典洪水问题算法 class Solution { public:int numIslands(vector<vector<char>>& grid) {int nr grid.size…...

docker 启动 redis 同时设置密码,关机后会自动重启
以下是使用Docker启动Redis并设置密码,并配置容器自动重启的命令: docker run -d \--name redis \--restartalways \-p 6379:6379 \redis:latest \redis-server --requirepass "your_strong_password"详细解释: docker run -d&am…...

3D Gaussian Splatting代码详解(一):模型训练、数据加载
1.模型训练 训练流程:train.py中的training函数 这段代码实现了一个 3D 高斯模型的训练循环,旨在通过逐步优化模型参数,使其能够精确地渲染特定场景。以下是代码的详细解析: def training(dataset, opt, pipe, testing_iteratio…...

docker部署RustDesk自建服务器
客户端: Releases rustdesk/rustdesk GitHub 服务端: 项目官方地址:GitHub - rustdesk/rustdesk-server: RustDesk Server Program 1、拉取RustDesk库 docker pull rustdesk/rustdesk-server:latest 阿里云库: docker pu…...

工作实战总结与实现-mybatis-plus更新策略部分字段不更新问题
文章目录 案例场景存在问题解决方案一解决方案二继续延伸 案例场景 很简单的工作场景,需要将数据库某个表的字段设置为null或者空字符串,使用mybatis-plus的update语句,如下: order.setPassCode(null);reservationOrderManger.up…...

MFC扩展库BCGControlBar Pro v36.0新版亮点:黑色主题中的自动反转图标
BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中,并为您节省数百个开发和调试时间。 BCGControlBar专业版 v36.0已全新发布了,这个版本在黑暗主题中添加自动图标反转、新增一个全新的S…...

Midjourney Describe API 的对接和使用
Midjourney Describe API 的对接和使用 Midjourney Describe API 的主要功能是通过上传图片,获取对图片的描述。使用该 API,只需要传递图片文件地址,API 会返回图片的详细描述。无需繁琐的参数设置,即可获得高质量的图片描述。 …...

《单片机原理及接口技术》(C51编程)(第三版)------张毅刚主编
1.整体框架:1-22题(17-20为编程题分别源自数中的P98,P162,P177页) 2.简答题部分: 3.计算题...

Qt入门9——绘图
基本概念 虽然Qt已经内置了很多的控件,但是不能保证现有控件就可以应对所有场景. 很多时候我们需要更强的"DIY"能力; Qt 提供了画图相关的API,可以允许我们在窗口上绘制任意的图形形状,来完成更复杂的界面设计。 绘图api核心类: 类说明QPaint…...

FreeRTOS之ARM CR5栈结构操作示意图
FreeRTOS之ARM CR5栈结构操作示意图 1 FreeRTOS源码下载地址2 ARM CR5栈结构操作宏和接口2.1 portSAVE_CONTEXT宏2.1.1 portSAVE_CONTEXT源码2.1.2 portSAVE_CONTEXT宏操作栈结构变化示意图 2.2 portRESTORE_CONTEXT宏2.2.1 portRESTORE_CONTEXT源码2.2.2 portRESTORE_CONTEXT宏…...

Java线程的interrupt中断、wait-notify/all(源码级分析)
实例方法: interrupt()方法是设置结束阻塞(sleep、),并且设置中断标记true isInterrupted()判断当前是否中断 静态方法: Thread.interrupted():调用这个方法的线程中断标记位还原为false 那么好,既然上面的方法作用是清晰的&…...

计网408考点讲解
IPv4...

当linux可执行文件缺少或者不兼容so库时候,如何查看版本以及缺少那些库
解决方法: ldd 命令来验证程序是否加载了正确的库: 如检查linear_elasticity可执行文件缺少的库,用下面命令: ldd linear_elasticity 可以发现下面not found就是缺少的库,还有对应的库的位置已经版本 $ ldd lin…...

文件下载的几种方式
1、使用window.open方法 url: 可以为文件存放的地址 function downloadFile(url) {window.open(url); }2、使用<a>标签进行文件下载 <a href"/多因素登录说明文档.pdf" class"link-text">说明文档</a> 3、使用fetch和Blob对象 这种…...

车联网安全学习之TBOX
Telematics BOX,简称 T-BOX,也称远程信息处理控制单元(Telematics Control Unit, TCU),集成GPS、外部通信接口、电子处理单元、微控制器、移动通信单元和存储器等功能模块。 TBOX 提供的功能有网络接入、OTA、远程控制…...