SpringMVC中的注解、JSON注解使用
Author:Exchanges
Version:9.0.2
1.RequestMapping详解
1.1作用
RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系
1.2使用
RequestMapping注解可以作用在方法和类上
作用在类上:第一级的访问目录
作用在方法上:第二级的访问目录注意:/ 表示应用的根目录开始
1.3属性
RequestMapping的属性
path: 指定请求路径的url
value: value属性和path属性是一样的
method: 指定该方法的请求方式
params: 指定限制请求参数的条件
headers: 发送的请求中必须包含的请求头
1.4测试
在UserController中添加无返回值方法进行测试
@RequestMapping(path = "/register",
method = RequestMethod.POST, params = "name",headers = "password")
public void register(HttpServletRequest request){
System.out.println("register..");
String name = request.getParameter("name");
System.out.println(name);
String password = request.getHeader("password");
System.out.println(password);
}
2.请求参数的绑定
2.1绑定机制
表单提交的数据都是k=v格式的 username=jack&password=123
SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
要求:提交表单的name和参数的名称是相同的
2.2支持的数据类型
基本数据类型和字符串类型
实体类型(JavaBean)
集合数据类型(List、map集合等)
2.3参数绑定事项
1.提交表单中name属性的值要和Controller中方法参数的名称是相同的,区分大小写
2.如果Controller中方法参数是实体类类型(JavaBean),要求提交表单的name属性的值要和JavaBean中的属性名称保持一致
3.如果实体类类型(JavaBean)中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性
4.实体类类型(JavaBean)中List和Map属性数据封装: list[index].属性名 和 map['key'].属性名
5.实体类类型(JavaBean)中Date类型属性数据封装,页面输入参数格式是 2019/1/1 可以自动参数绑定,如果页面输入参数格式是 2019-1-1 则无法绑定,我们需要在对应的Date类型的属性上加上@DateTimeFormat(pattern = "yyyy-MM-dd") 注解格式化日期
2.3.1创建register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<center>
<form action="/user/register">
用户名:<input type="text" name="name"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="注册">
</form>
<hr>
<form action="/user/register">
用户名:<input type="text" name="name"><br>
密码:<input type="password" name="password"><br>
List:<input type="text" name="list[1].cname"><br>
Map:<input type="text" name="map['firstcar'].cname"><br>
Birthday:<input type="date" name="birthday"><br>
<input type="submit" value="注册">
</form>
</center>
</body>
</html>
2.3.2创建User
package com.qf.pojo;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Data
public class User {
private String name;
private String password;
private List<Car> list;
private Map<String,Car> map;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
}
2.3.3创建Car
package com.qf.pojo;
import lombok.Data;
@Data
public class Car {
private Integer cid;
private String cname;
}
2.3.4在UserController添加方法测试
//参数名要和表单中name属性的属性值一致
// @RequestMapping("register")
// public void register(String name,String password){
// System.out.println(name + "--" + password);
// }
//对象的属性名要和表单中name属性的属性值一致
@RequestMapping("register")
public void register(User user){
System.out.println(user);
}
2.4常用注解
2.4.1@RequestParam注解
作用:把请求中的指定名称的参数传递给控制器中的形参赋值
属性
value:请求参数中的名称
required:请求参数中是否必须提供此参数,默认值是true,必须提供
<!-- 测试@RequestParam -->
<a href="user/testRequestParam?uid=123">testRequestParam</a>
<%--<a href="user/testRequestParam">testRequestParam</a>--%>
//测试@RequestParam注解
@RequestMapping("testRequestParam")
public void testRequestParam(@RequestParam(value = "uid",required = false,defaultValue = "1001") Integer id){
System.out.println(id);
}
2.4.2@PathVariable注解
作用:拥有绑定url中的占位符的。url中有/delete/{id},{id}就是占位符
属性
value:指定url中的占位符名称Restful风格的URL优点
结构清晰
符合标准
易于理解
扩展方便
<!-- 测试@PathVariable -->
<a href="user/testPathVariable/12345">testPathVariable</a>
//测试@PathVariable注解
//{id}表示占位符
@RequestMapping("testPathVariable/{id}")
public void testPathVariable(@PathVariable("id") Integer uid){
System.out.println(uid);
}
2.4.3@RequestHeader注解
作用:获取指定请求头的值
属性
value:请求头的名称
<!-- 测试@RequestHeader -->
<a href="user/testRequestHeader">testRequestHeader</a>
//测试@RequestHeader注解
@RequestMapping("testRequestHeader")
public void testRequestHeader(@RequestHeader("host") String host){
System.out.println(host);
}
2.4.4@CookieValue注解
作用:用于获取指定cookie的名称的值
属性
value:cookie的名称
<!-- 测试@CookieValue -->
<a href="user/testCookieValue">testCookieValue</a>
//测试@CookieValue注解
@RequestMapping("testCookieValue")
public void testCookieValue(@CookieValue("JSESSIONID") String JSESSIONID){
System.out.println(JSESSIONID);
}
3.响应数据和结果视图
3.1返回值分类
返回字符串:String
Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。
应用时可以设置参数类型为Model,使用Model对象调用addAttribute方法来存储数据。返回值是void
如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。
应用时可以设置参数类型为HttpServletRequest和HttpServletResponse,使用转发或者重定向来跳转页面返回值是ModelAndView对象
ModelAndView对象是Spring提供的一个对象,可以调用addObject方法来保存数据以及调用setViewName方法来跳转页面.使用forward关键字进行请求转发
return "forward:转发的JSP路径"使用redirect关键字进行重定向(默认会把项目路径加上)
return "redirect:重定向的JSP路径"
3.2 代码测试
3.2.1导入依赖
<dependencies>
<!-- spring-webmvc依赖中传递了spring的核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<!-- tomcat中自带servlet和jsp的jar包,这里根据需求导入 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
3.2.2创建User
package com.qf.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private String password;
}
3.2.3创建UserController
package com.qf.controller;
import com.qf.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("findAll")
public void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//模拟数据库数据
ArrayList<User> users = new ArrayList<>();
users.add(new User(1001,"张三","123"));
users.add(new User(1002,"李四","456"));
users.add(new User(1003,"王五","789"));
//保存数据
request.setAttribute("users",users);
//跳转页面
request.getRequestDispatcher("/WEB-INF/jsp/list.jsp").forward(request,response);
}
//常用返回值:String类型
@RequestMapping("testStringFindAll")
public String testStringFindAll(Model model){
//模拟数据库数据
ArrayList<User> users = new ArrayList<>();
users.add(new User(1001,"张三","123"));
users.add(new User(1002,"李四","456"));
users.add(new User(1003,"王五","789"));
//保存数据
model.addAttribute("users",users);
//可以根据视图解析器的配置而改变
return "/WEB-INF/jsp/list.jsp";
}
@RequestMapping("testForwardFindAll")
public String testForwardFindAll(Model model){
//模拟数据库数据
ArrayList<User> users = new ArrayList<>();
users.add(new User(1001,"张三","123"));
users.add(new User(1002,"李四","456"));
users.add(new User(1003,"王五","789"));
//保存数据
model.addAttribute("users",users);
return "forward:/WEB-INF/jsp/list.jsp";
}
@RequestMapping("testRedirect")
public String testRedirect(Model model){
//重定向:一般用于调用其他方法
return "redirect:/user/testStringFindAll";
}
}
3.2.4在\webapp\WEB-INF\jsp目录下创建list.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:forEach items="${users}" var="user">
${user.id} -- ${user.name} -- ${user.password} <br>
</c:forEach>
</body>
</html>
3.2.5配置web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 配置前端控制器,否则访问404 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 加载配置文件 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3.2.6配置springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置spingmvc组件 -->
<mvc:annotation-driven/>
<!-- 扫描包下注解 -->
<context:component-scan base-package="com.qf"></context:component-scan>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置前缀 -->
<!-- <property name="prefix" value="/WEB-INF/jsp"></property>-->
<!-- 设置后缀 -->
<!-- <property name="suffix" value=".jsp"></property>-->
</bean>
</beans>
3.2.7测试即可
访问对应的路径进行测试:http://localhost:8080/user/findAll
4.Json相关
4.1介绍
常用的Json框架:Jackson FastJson Gson
JavaBean序列化转换为Json格式,性能:Jackson > FastJson > Gson > Json-lib
Jackson常用注解
@JsonProperty("别名") : 给属性指定别名
@JsonIgnore : 指定属性不返回
@JsonFormat(pattern = "yyyy-MM-dd",locale = "zh",timezone = "GMT+8") : 格式化日期属性
4.2@ResponseBody注解
作用:用于响应json类型的数据
4.2.1导入依赖
<dependencies>
<!-- spring-webmvc依赖中传递了spring的核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<!-- tomcat中自带servlet和jsp的jar包,这里根据需求导入 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
</dependencies>
4.2.2编写User
package com.qf.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
@JsonProperty("名字")
private String name;
@JsonIgnore//忽略当前属性
private String password;
@JsonFormat(pattern = "yyyy-MM-dd",locale = "zh",timezone = "GMT+8")
private Date birthday;
}
4.2.3编写UserController
package com.qf.controller;
import com.qf.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
//@RestController = @Controller + @ResponseBody
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("findById")
@ResponseBody
public User findById(Integer id) {
//模拟数据库查到的数据
User db_user = new User(id, "杰克", "123", new Date());
//返回
return db_user;
}
@RequestMapping("findAll")
@ResponseBody
public List<User> findAll(){
//模拟数据库查到的数据
List<User> userList = new ArrayList<>();
userList.add(new User(1001,"张三","123",new Date()));
userList.add(new User(1002,"李四","456",new Date()));
userList.add(new User(1003,"王五","789",new Date()));
//返回
return userList;
}
}
4.2.4配置web.xml和springmvc.xml,进行测试
4.3@RequestBody注解
用于接收前端传过来的json类型的数据(注意:GET方式请求不可以)
4.3.1在springmvc.xml中放行静态资源
<!-- 设置所有静态资源不被拦截 -->
<mvc:default-servlet-handler/>
4.3.2创建ajax.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<!-- 导入官方jquery.js -->
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>
<body>
<input type="button" value="测试json数据" onclick="test()">
</body>
<script type="application/javascript">
function test(){
$.ajax({
type: "POST",
url: "/user/testRequestBody",
contentType: "application/json;charset=UTF-8",
data: '{"id":1001,"name":"jack","password":"123","birthday":"2022-1-1"}',
success: function(msg){
alert( "后端方法返回值: " + msg );
}
});
}
</script>
</html>
4.3.3修改User
把@JsonProperty 和 @JsonIgnore注释掉
package com.qf.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
//@JsonProperty("名字")
private String name;
//@JsonIgnore//忽略当前属性
private String password;
@JsonFormat(pattern = "yyyy-MM-dd",locale = "zh",timezone = "GMT+8")
private Date birthday;
}
4.3.4.在Controller中添加方法
@RequestMapping("testRequestBody")
@ResponseBody
public String testRequestBody(@RequestBody User user) {
System.out.println("获取前端json数据:" + user);
return "success";
}