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,进行测试

访问测试:http://localhost:8080/user/findById?id=1

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";
}
posted @ 2022-07-10 18:20  qtyanan  阅读(254)  评论(0编辑  收藏  举报