SpringMVC框架

导读:本篇文章讲解 SpringMVC框架,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

SpringMVC框架

目录

一、入门案例

1.创建项目并搭建tomcat服务器

创建项目
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
搭建tomcat服务器,此处省略,可以参考我以前的博客。

2.导入依赖

pom.xml


  <packaging>war</packaging>

 <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>

    <!-- 引入springmvc 相关jar包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.0.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

3.springMVC.xml的配置

resources下的
springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">

   <!--ioc的容器扫描器-->
    <context:component-scan base-package="com.bjpowernode.controller"/>
    <!--mvc注解驱动-->
    <mvc:annotation-driven/>
</beans>

4.web.xml的配置

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>


  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <!--springMVC配置文件的位置
              classPath:字节码的输出路径
      -->
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springMVC.xml</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

com.bjpowernode.controller
HelloController.java

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/controller")// 类的映射路径 ,其实应当加上,原因:映射路径在整个项目中的要唯一,
// 然后 如果不添加类上的映射路径那么方法上的映射路径 很很难去维护 ,定义唯一性就很麻烦
// 如果有了类的映射路径,那么不同的controller中,方法的映射路径可以相同
// 我们只要保证 方法的映射路径在当前controller类中唯一就可以了
public class HelloController {

    @RequestMapping("/hello")// 方法的映射路径
    @ResponseBody// 把数据转成json 返回给浏览器
    public String index(){
        return "hello springMVC";
    }

}

二、数据绑定

1.导入依赖

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjpowernode</groupId>
    <artifactId>02-DataBindSpringMVC</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <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>
        <!-- 引入springmvc 相关jar包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>



</project>

2.springMVC.xml的配置(有增加)

resources文件夹下springMVC.xml配置文件
需要添加:处理静态资源被拦截的请求 静态资源被放行
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">

    <!--ioc 扫描器-->
    <context:component-scan base-package="com.bjpowernode.controller"/>
    <!--注解驱动,作用:加载最新的处理器映射器,处理器适配器和视图解析器-->
    <mvc:annotation-driven/>

    <!--处理静态资源被拦截的请求 静态资源被放行-->
    <mvc:default-servlet-handler/>


</beans>

3.web.xml的配置

webapp下的WEB-INF下的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>


  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <!--springMVC配置文件的位置
              classPath:字节码的输出路径
      -->
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springMVC.xml</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

前端页面
data.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/data/base" method="post">
    昵称:<input type="text" name="name" /> <br/>
    密码:<input type="password" name="password" /> <br/>
    性别:<input type="radio" name="sex" value="1" checked /><input type="radio" name="sex"  value="0"/><br/>
    爱好:<input type="checkbox" name="hobby"  value="c"/>c
    <input type="checkbox" name="hobby"  checked value="java"/>java <br/>
    常住地:<select  name="City" >
    <option value="cd">成都</option>
    <option value="bj">北京</option>
    <option value="sy">三亚</option>
</select><br/>
    <input type="submit" value="提交"/>

</form>
</body>
</html>

4.controller层

com.bjpowernode.controller
DataController.java

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;

@Controller
@RequestMapping("/data")
public class DataController {



    @RequestMapping("/base")
    @ResponseBody
    public String baseMethod(String name,String password,String sex,String[] hobby, String city){
        System.out.println("name = " + name);
        System.out.println("password = " + password);
        System.out.println("sex = " + sex);
        System.out.println(Arrays.toString(hobby));
        System.out.println("city = " + city);

        return "index";// 如果不使用ResponseBody注解 表示 index 表示页面,它主动去寻找index页面
    }

   

  
}

运行并提交数据
在这里插入图片描述
运行结果如下:
在这里插入图片描述
结果发现city = null
结论:
/*
* 获取表单中参数的时候,
* 一定要保证 获取的参数的变量名称表单中的控件的name属性的名称一致
*
* 如果非要以名称不一致的方式,接收表单的属性的名称,则采用自定义的方式 ,那么需要使用@RequestParam 注解来解决
*
*/

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;

@Controller
@RequestMapping("/data")
public class DataController {

    //@RequestParam注解 解决前端表单字段和后端接收的字段不一致的问题
    @RequestMapping("/base")
    @ResponseBody
    public String baseMethod(String name,String password,String sex,String[] hobby, @RequestParam("City") String city){
        System.out.println("name = " + name);
        System.out.println("password = " + password);
        System.out.println("sex = " + sex);
        System.out.println(Arrays.toString(hobby));
        System.out.println("city = " + city);

        return "index";// 如果不使用ResponseBody注解  index 表示页面,它主动去寻找index页面
    }


}

运行结果如下:
在这里插入图片描述
接收数据的类型,可以使用非字符串类型,springmvc框架把接收表单的数据转换成了你想接收的数据类型 (日期类型除外)
案例:前端传String sex -> 后端用int sex接收

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;

@Controller
@RequestMapping("/data")
public class DataController {



    //前端传String sex -> 后端用int sex接收
    @RequestMapping("/base")
    @ResponseBody
    public String baseMethod(String name,String password,int sex,String[] hobby, @RequestParam("City") String city){
        System.out.println("name = " + name);
        System.out.println("password = " + password);
        System.out.println("sex = " + sex);
        System.out.println(Arrays.toString(hobby));
        System.out.println("city = " + city);

        return "index";// 如果不使用ResponseBody注解 表示 index 表示页面,它主动去寻找index页面
    }
}

运行结果如下:
在这里插入图片描述

5.把参数封装成module层的实体Bean

在这里插入图片描述

package com.bjpowernode.domain;

import lombok.Data;
import org.springframework.web.bind.annotation.RequestParam;

@Data
public class User {
    private String name;
    private String password;
    private int sex;
    private String[] hobby;
    private String City;
}

controller层
DataController.java

package com.bjpowernode.controller;

import com.bjpowernode.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;

@Controller
@RequestMapping("/data")
public class DataController {

    
    @RequestMapping("/base")
    @ResponseBody
    public String baseMethod(User user){
        System.out.println("name = " + user.getName());
        System.out.println("password = " + user.getPassword());
        System.out.println("sex = " + user.getSex());
        System.out.println(Arrays.toString(user.getHobby()));
        System.out.println("city = " + user.getCity());

        return "index";// 如果不使用ResponseBody注解 表示 index 表示页面,它主动去寻找index页面
    }
}

运行结果
在这里插入图片描述
在这里插入图片描述
运行结果
在这里插入图片描述
得到结论
是根据setter方法来赋值的
在这里插入图片描述
运行结果
在这里插入图片描述

6.用Map封装参数

一般用于只使用一次
DataController.java

package com.bjpowernode.controller;

import com.bjpowernode.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.HashMap;

@Controller
@RequestMapping("/data")
public class DataController {




    /*
     *  针对使用map容器封装数据, 一个key 对应多个值的情况,是封装不进去的,需要单独获取
     */
    @RequestMapping("/base")
    @ResponseBody
    public String baseMethod(@RequestParam HashMap<String,Object> map,String[] hobby){
        System.out.println("name = " + map.get("name"));
        System.out.println("password = " + map.get("password"));
        System.out.println("sex = " + map.get("sex"));
        System.out.println(Arrays.toString(hobby));
        System.out.println("city = " + map.get("City"));

        return "index";// 如果不使用ResponseBody注解 表示 index 表示页面,它主动去寻找index页面
    }
}

7.用List封装参数

DataController.java

package com.bjpowernode.controller;

import com.bjpowernode.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.HashMap;
import java.util.*;

@Controller
@RequestMapping("/data")
public class DataController {

    /*
     *   使用list 接收
     *   第一必须要使用@RequestParam 注解 ,
     *   第二要保证 接收的变量名称和表单中变量名称一致
     *   如果不一致 必须要在注解中配置一个和表单中的名称一致的字符串
     **/
    @RequestMapping("/base")
    @ResponseBody
    public String baseMethod(@RequestParam("hobby") List<String> hobbyh){
        hobbyh.forEach(System.out::println);

        return "index";// 如果不使用ResponseBody注解 表示 index 表示页面,它主动去寻找index页面
    }

}

三、跳转

配置页面模板之前
controller层
ForwardController.java

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/forward")
public class ForwardController {

    @RequestMapping("/list")
    public String list(){
        return "/WEB-INF/view/department/list.jsp";
    }

}

按照以下路径,建立页面
在这里插入图片描述
list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
我是jsp
</body>
</html>

运行结果
在这里插入图片描述

页面模板的设置

问题: 当我们每个方法返回的页面都在WEB-INF下面,每个页面后缀都是jsp,这么相同的部分应该合理的抽取起来,而不是每次都去编写它
方案:重新配置视图解析器,在视图解析器里面 通过配置前缀和后缀来完成抽取工作
springMVC.xml配置文件中
在这里插入图片描述

springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">

    <!--ioc 扫描器-->
    <context:component-scan base-package="com.bjpowernode.controller"/>
    <!--注解驱动,作用:加载最新的处理器映射器,处理器适配器和视图解析器-->
    <mvc:annotation-driven/>

    <!--处理静态资源被拦截的请求 静态资源被放行-->
    <mvc:default-servlet-handler/>

    <!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="suffix" value=".jsp"/>
        <property name="prefix" value="/WEB-INF/view"/>

    </bean>

</beans>

ForwardController.java

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/forward")
public class ForwardController {

    @RequestMapping("/list")
    public String list(){
        /*有对访问的资源的路径 进行抽取处理,所以路径内容要写很多*/
//        return "/WEB-INF/view/department/list.jsp";

        /*把页面 共同的部分进行抽取,因此 我们只需要在 返回值中 写 不同的部分*/
        //在springMVC.xml配置文件中对文件的前缀和后缀进行抽取
        return "/department/list";
    }

}
/*总有特殊情况,如果 访问的页面不存在共同的部分,不应该把共同的部分进行拼接
 *  可以使用关键字(forward,redirect),重置路径
 * forward 属于请求转发, 默认值
 * redirect 属于重定向
 */

ForwardController.java

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/forward")
public class ForwardController {

    @RequestMapping("/list")
    public String list(){
        /*有对访问的资源的路径 进行抽取处理,所以路径内容要写很多*/
//        return "/WEB-INF/view/department/list.jsp";

        /*把页面 共同的部分进行抽取,因此 我们只需要在 返回值中 写 不同的部分*/
        //在springMVC.xml配置文件中对文件的前缀和后缀进行抽取
        return "/department/list";
    }

    /*总有特殊情况,如果 访问的页面不存在共同的部分,不应该把共同的部分进行拼接
     *  可以使用关键字(forward,redirect),重置路径
     * forward 属于请求转发, 默认值
     * redirect 属于重定向
     *
     */
    @RequestMapping("/login")
    public String login(){
//        return "forward:/login.jsp";
        return "redirect:/login.jsp";
    }

}
login.jsp
在这里插入图片描述
login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
我是login.jsp
</body>
</html>

四、支持内置的对象

在SpringMVC中,支持为处理器中的方法注入内置的对象,如:HttpServletRequest、HttpServletResponse、HttpSession、Model等。
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjpowernode</groupId>
    <artifactId>04-scopeobjectproject</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <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>
        <!-- 引入springmvc 相关jar包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>



</project>

springMVC.xml和web.xml的配置参考前面一或二
ScopeController.java

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Controller
@RequestMapping("/scope")
public class ScopeController {

   /*可以继续使用传统方式 */
   @RequestMapping("/listTranditional")
   public void list(HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model) throws ServletException, IOException {

      // 三个域对象存数据
      request.setAttribute("req","request");
      session.setAttribute("ses","session");
      model.addAttribute("m","model");

      // 请求转发
      request.getRequestDispatcher("/WEB-INF/view/department/list.jsp").forward(request,response);
   }

   /*springmvc 提供的跳转方式  注意: model的使用 必须在 sprigMVC 框架中使用*/
   @RequestMapping("/listSpringMVC")
    public String list(HttpServletRequest request, HttpSession session, Model model){

      // 三个域对象存数据
       request.setAttribute("req","request");
       session.setAttribute("ses","session");
       model.addAttribute("m","model");

      // 请求转发
       return "/department/list";
   }
}

src\main\webapp\WEB-INF\view\department\list.jsp
list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--从域对象中获取数据,一般都是使用model,因为 不需要导入Servlet的包--%>
<%--如果往session中存入数据 必须要导入servlet的包--%>
我是jsp
request:${req} <br/>
session:${ses} <br/>
model:${m} <br/>
</body>
</html>

运行结果
传统方式
在这里插入图片描述
springmvc 提供的跳转方式
在这里插入图片描述

五、SpringMVC返回JSON

在springmvc中,默认返回的数据不论是什么格式,都当做视图进行解析。会根据返回值的toString的结果,当做路径去查找视图的模板,如果想要返回JSON,则需要使用注解,标识该方法返回的是JSON数据,不要当做视图路径进行路径的查找.该注解为:@ResponseBody.因为springmvc有内置的消息转换器(整合了Jackson),如果想要特殊设置,需要进行XML配置.

5.1.XML配置的形式

XML配置形式,是修改了默认结果处理,全局生效的。使用注解@ResponseBody,标识该方法返回的内容不是URL地址,而是一个消息,使用输出对象输出给客户端。
@RequestMapping
name : 方法映射名称
value/path : 方法访问路径
method : 支持的请求的方法类型:
GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE
params : 请求必须有的参数
headers : 请求必须有的头信息
consumes : 指定请求的数据格式类型 : 普通文本、表单格式、JSON
produces : 指定返回数据的格式类型 :JSON 、HTML

5.1.1 配置编码过滤器

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>

    <!-- 编码过滤器 -->
    <filter>
        <filter-name>charsetFilter</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>charsetFilter</filter-name>
        <!-- 只对springmvc处理的请求进行编码过滤 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--springmvc的配置的文件的位置
              classPath: 字节码的输出路径
             -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>



</web-app>

5.1.2 @RequestMapping注解及其参数

params

在这里插入图片描述

在这里插入图片描述

headers

在这里插入图片描述
在这里插入图片描述

consumers


在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
注意:后端Controller不加@RequestBody注解,则获取不到请求的user信息

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

producers

在这里插入图片描述

在这里插入图片描述

5.1.3 module层

com.bjpowernode.domain

package com.bjpowernode.domain;

import lombok.Data;

@Data
public class User {
    private String username;
    private Integer age;

}

5.1.4 controller层

RequestMappingController.java

package com.bjpowernode.web.controller;


import com.bjpowernode.domain.User;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Controller
@RequestMapping("/req")
public class RequestMappingController {


    /*
     * value 属性 和  path 属性  可以等量代换
     * */
    @RequestMapping(path = "/index") //  @RequestMapping(value = "/index") @RequestMapping("/index")
    @ResponseBody
    public String index() {
        return "hello requestMapping";
    }

    /*
     * method = RequestMethod.POST  限制访问该方法的请求方式  例如:RequestMethod.POST 必须使用post请求来访问
     * 目的: 增加一份安全   @RequestMapping(value = "/index2", method = RequestMethod.POST) 等价于  @PostMapping("/index2")
     * */
    @RequestMapping(value = "/index2",method = RequestMethod.POST)
//    @PostMapping("index2")
    @ResponseBody
    public String index2() {
        return "hello requestMapping";
    }

    /*
     * params = {"username=admin","pwd=123"}  要求访问者 必须在地址栏携带规定的参数
     * 目的: 增加一份安全
     * */
    @RequestMapping(value = "/index3",params = {"username=admin","pwd=123"})
    @ResponseBody
    public String index3() {
        return "hello requestMapping";
    }

    /*
     * headers={"myhead=hello"}   要求访问者必须在请求头信息中携带自定义的头信息
     * 目的:可以携带token
     * */
    @RequestMapping(value = "/index4", headers={"myhead=hello"})
    @ResponseBody
    public String index4() {
        return "hello requestMapping";
    }

    /*
    consumes = {"application/json"}  发送请求,参数的类型 必须是 json格式

    目的: 限制前端发送参数类型  限制 的 请求
 */
    @RequestMapping(value = "/index5",consumes = {"application/json"})
    @ResponseBody
    public String index5( @RequestBody User user ) {
//        System.out.println("map = " + map);
        System.out.println("username = "+  user.getUsername());
        System.out.println("age = " + user.getAge());
        return "hello requestMapping";
    }

    /*
     * produces = {"application/json"} 响应数据的类型的 限制,必须响应json格式
     *  目的: 限制后台发送数据给前端  限制 的 响应
     *  一般省略不写,因为 使用注解 @ResponseBody  表示响应的数据为json  (开发中,网络之间传递数据 采用的格式 99% 的采用json)
     * */
    @RequestMapping(value = "/index6",produces = {"application/json"})
    @ResponseBody
    public String index6() {
        return "hello requestMapping";
    }

}

六、使用Jackson处理中文乱码和日期参数

6.0 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>

    <!-- 编码过滤器 -->
    <filter>
        <filter-name>charsetFilter</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>charsetFilter</filter-name>
        <!-- 只对springmvc处理的请求进行编码过滤 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--springmvc的配置的文件的位置
              classPath: 字节码的输出路径
             -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>



</web-app>

6.1 pom.xml

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjpowernode</groupId>
    <artifactId>07-jacksonProject</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <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>
        <spring.version>5.2.0.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--springmvc-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.7</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!--tool-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>

        <!--log-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.3</version>
        </dependency>

    </dependencies>


</project>

6.2 module层对象

com.bjpowernode.domain
User.java

package com.bjpowernode.web.controller;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

@Data
public class User {

    private Long id;
    private String name;
    private Integer age;
//    @DateTimeFormat(pattern = "yyyy-MM-dd")
//    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") // 负责输出日期参数
    private Date birthday;
}

6.3 controller层

package com.bjpowernode.web.controller;

import com.bjpowernode.domain.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Controller
@RequestMapping("/jack")
public class JacksonController {


    @RequestMapping("/index")
    @ResponseBody
    public String index(){
        return "hello jackson";
    }

    @RequestMapping("/index2")
    @ResponseBody
    public String index2(){
        List<User> list = new ArrayList<>();
        User user = new User();
        user.setId(1L);
        user.setName("武媚娘");
        user.setAge(122);
        user.setBirthday(new Date());

        User user1 = new User();
        user1.setId(2L);
        user1.setName("赵匡胤");
        user1.setAge(12);
        user1.setBirthday(new Date());

        list.add(user);
        list.add(user1);

        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = "";
        try {
            jsonStr = objectMapper.writeValueAsString(list);

        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return jsonStr;
    }

    /*接收日期
     *   从页面 到 后台 处理日期 接收的是单个日期参数
     *  接收日期类型的参数的时候 使用 @DateTimeFormat(pattern = "yyyy-MM-dd")
     * */
    @RequestMapping("/index3")
    @ResponseBody
    public Date index3(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){

       return birthday;
    }

    /*接收日期
     *   从页面 到 后台 处理日期 接收的是 封装了日期参数的对象
     *  在类中的日期属性上 使用 @DateTimeFormat(pattern = "yyyy-MM-dd")
     * */
    @RequestMapping("/index4")
    @ResponseBody
    public String  index4(User user){

        System.out.println("user = " + user);
        return "接收对象参数";
    }

    /*
     *   响应日期参数给浏览器

     *   从后台 到 页面 处理日期 响应一个带有日期参数属性的对象
     *   方案一:在类中的日期属性上 使用  @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
     *   方案二:配置转换器
     */
    @RequestMapping("/index5")
    @ResponseBody
    public User index5(){

        User user = new User();
        user.setBirthday(new Date());
        user.setAge(23);
        user.setName("我是中文");
        user.setId(3L);

        return user;
    }
}

6.4 前段页面

src\main\webapp
index4.html发送的请求对应的Controller里面的index4方法
这个页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/jack/index4" method="post">
    姓名:<input type="text" name="name"/><br/>
    年龄:<input type="text" name="age"/><br/>
    生日:<input type="date" name="birthday"/><br/>
    <input type="submit" value="注册"/>
</form>
</body>
</html>

6.5 springMVC.xml配置文件

6.5.1 方案一 springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">



    <!--ioc扫描器-->
    <context:component-scan base-package="com.bjpowernode.web"/>
    <!--mvc 注解驱动-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!--解决中文乱码问题
           如果返回值是对象,自动解决了中文的问题,例子:http://localhost:8080/jack/index5
           如果返回是json格式的字符串,需要通过下面来解决中文问题 例子:http://localhost:8080/jack/index2
           -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <!--解决日期的问题  前提是没有使用注解的情况下,如果返回值是对象,需要通过下面的来解决日期问题
            如果返回是json格式的字符串,日期问题不能通过下面来解决-->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="dateFormat">
                            <bean class="java.text.SimpleDateFormat">
                                <constructor-arg name="pattern" value="yyyy-MM-dd"/>
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!--处理静态资源-->
    <mvc:default-servlet-handler/>
    <!--视图解析器,配置模板-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

6.5.2 方案二 springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">



    <!--ioc扫描器-->
    <context:component-scan base-package="com.bjpowernode.web"/>
    <!--mvc 注解驱动-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!--解决中文乱码问题
            如果返回值是对象,自动解决了中文的问题,例子:http://localhost:8080/jack/index5
            如果返回是json格式的字符串,需要通过下面来解决中文问题 例子:http://localhost:8080/jack/index2
            -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <!--解决日期的问题  需要下面的配置 且 必须配置注解-->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper" ref="jacksonObjectMapper" />
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <bean id="jacksonObjectMapper" class="com.bjpowernode.jackson.CustomObjectMapper" />

    <!--处理静态资源-->
    <mvc:default-servlet-handler/>
    <!--视图解析器,配置模板-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

6.6 方案二 添加的其他类的代码

com\bjpowernode\jackson
CustomObjectMapper,java

package com.bjpowernode.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;
import java.util.TimeZone;

public class CustomObjectMapper extends ObjectMapper {
	private static final long serialVersionUID = 1L;
	
	public CustomObjectMapper() {
		//禁止使用时间戳
		this.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
		//设置为中国上海时区
		this.setTimeZone(TimeZone.getTimeZone("GMT+8"));
		//设置日期格式
		this.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
		
		//反序列化时,属性不存在的兼容处理  
		//this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);  
		//如果是空对象的时候,不抛异常
		//this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		//反序列化的时候如果多了其他属性,不抛出异常
        //this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);  
        //单引号处理  
        //this.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); 
	}

}

6.6.5 以下是原理讲解

6.7 Jackson 解决中文乱码问题

情况一:返回值是对象(不需要配置)

不需要在springMVC.xml配置,自动解决了中文乱码的问题
在这里插入图片描述
在这里插入图片描述

情况二:返回值是JSON格式的字符串(配置xml)

需要配置springMVC.xml
在这里插入图片描述
如果不在springMVC.xml配置,则出现中文乱码问题
在这里插入图片描述
配置SpringMVC.xml过后
在这里插入图片描述
中文乱码问题得到解决
在这里插入图片描述

6.8 Jackson 解决日期格式问题

一、 方案一

1. 后端返回给前端的数据

在这里插入图片描述

1.1 返回值是对象(xml或@JsonFormat)

在这里插入图片描述

1.1.1 解决办法一:配置xml

配置SpringMVC.xml

在这里插入图片描述

1.1.2 解决办法二:@JsonFormat

module层的User类的Date类型的日期字段,配置@JsonFormat(pattern = “yyyy-MM-dd”,timezone = “GMT+8”)注解
在这里插入图片描述

1.2 返回值是JSON格式的字符串(@JsonFormat)

在这里插入图片描述
只能使用@JsonFormat注解
在这里插入图片描述

2.后端接收前端的数据

2.1 接收单个日期参数(@DateTimeFormat)

只能使用@DateTimeFormat注解
在这里插入图片描述

2.2 封装了日期参数的对象 (@DateTimeFormat)

在这里插入图片描述

解决办法只能配置注解@DateTimeFormat
在这里插入图片描述

二、 方案二

1. 后端返回给前端的数据

在这里插入图片描述

1.1 返回值是对象 (xml或@JsonFormat)

在这里插入图片描述

1.1.1 解决办法一:配置xml

配置SpringMVC.xml
在这里插入图片描述

1.1.2 解决办法二:@JsonFormat

在这里插入图片描述

1.2 返回值是JSON格式的字符串(@JsonFormat)

在这里插入图片描述
只能使用@JsonFormat注解
在这里插入图片描述

2.后端接收前端的数据

2.1 接收单个日期参数(xml)

只能配置xml
在这里插入图片描述

2.2 封装了日期参数的对象 (@DateTimeFormat)

在这里插入图片描述

解决办法只能配置注解@DateTimeFormat
在这里插入图片描述

三、小结

后端返回给前段数据
当返回值是对象的时候,用xml和@JsonFormat均可
当返回值是JSON格式的字符串时,只能用@JsonFormat

后端接收前段的数据
当接收单个日期参数时,方案一只能用@DataTimeFormat注解,方案二只能 用xml
当接收封装了日期参数的对象时,只能用@DataTimeFormat注解

@DataTimeFormat是SpringMVC框架的注解
@JsonFormat是Jackson的注解

七、FastJson 处理中文乱码和日期参数

7.0 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>

    <!-- 编码过滤器 -->
    <filter>
        <filter-name>charsetFilter</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>charsetFilter</filter-name>
        <!-- 只对springmvc处理的请求进行编码过滤 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--springmvc的配置的文件的位置
              classPath: 字节码的输出路径
             -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>



</web-app>

7.1 pom.xml

pom.xml导依赖
在这里插入图片描述
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjpowernode</groupId>
    <artifactId>09-fastjsonProject</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <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>
        <spring.version>5.2.0.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--springmvc-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.7</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!--tool-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>

        <!--log-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.12</version>
        </dependency>


    </dependencies>


</project>

7.2 module层

com.bjpowernode.domain
User.java

package com.bjpowernode.domain;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

@Data
public class User {

    private Long id;
    private String name;
    private Integer age;

//    @DateTimeFormat(pattern = "yyyy-MM-dd") // 接收日期参数
    @JSONField(format = "yyyy-MM-dd") // 响应日期类型数据
    private Date birthday;
}

7.3 controller层

FastJsonController.java

package com.bjpowernode.web.controller;

import com.alibaba.fastjson2.JSON;
import com.bjpowernode.domain.User;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Controller
@RequestMapping("/fast")
public class FastJsonController {


    @RequestMapping("/index")
    @ResponseBody
    public String index(){
        return "hello fastjson";
    }

    /*接收日期
     *   从页面 到 后台 处理日期 接收的是单个日期参数
     *   接收日期类型的参数的时候  使用 @DateTimeFormat(pattern = "yyyy-MM-dd")
     *
     * */
    @RequestMapping("/index2")
    @ResponseBody
    public String index2(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){
        System.out.println("birthday = " + birthday);
        return "接收一个日期参数";
    }

    /*接收日期
     *   从页面 到 后台 处理日期 接收的是 封装了日期参数的对象
     *  在类中的日期属性上 只能使用 @DateTimeFormat(pattern = "yyyy-MM-dd")
     * */
    @RequestMapping("/index3")
    @ResponseBody
    public String  index3(User user){

        System.out.println("user = " + user);
        return "接收对象参数";
    }

    /* 响应日期参数给浏览器

     *   从后台 到 页面 处理日期 响应一个带有日期参数的属性

     *   在类中的日期属性上 使用  @JSONField(format = "yyyy-MM-dd")
          如果返回的是对象,必须使用 转换器和xml
     *
     * */
    @RequestMapping("/index4")
    @ResponseBody
    public User index4(){

        User user = new User();
        user.setBirthday(new Date());
        user.setAge(23);
        user.setName("我是中文");
        user.setId(3L);

        return user;
    }

    /* 响应日期参数给浏览器

     *   从后台 到 页面 处理日期 响应一个JSON字符串
     *   在类中的日期属性上 使用  @JSONField(format = "yyyy-MM-dd") 和 xml
     *
     * */
    @RequestMapping("/index5")
    @ResponseBody
    public String index5(){
        List<User> list = new ArrayList<>();
        User user = new User();
        user.setId(1L);
        user.setName("武媚娘");
        user.setAge(122);
        user.setBirthday(new Date());

        User user1 = new User();
        user1.setId(2L);
        user1.setName("赵匡胤");
        user1.setAge(12);
        user1.setBirthday(new Date());

        list.add(user);
        list.add(user1);


        return JSON.toJSONString(list);
    }

    /* 响应日期参数给浏览器

     *   从后台 到 页面 处理日期 响应一个带有日期参数属性的对象的集合
     *   在类中的日期属性上 使用  @JSONField(format = "yyyy-MM-dd")
     *
     * */
    @RequestMapping("/index6")
    @ResponseBody
    public List<User> index6(){
        List<User> list = new ArrayList<>();
        User user = new User();
        user.setId(1L);
        user.setName("武媚娘");
        user.setAge(122);
        user.setBirthday(new Date());

        User user1 = new User();
        user1.setId(2L);
        user1.setName("赵匡胤");
        user1.setAge(12);
        user1.setBirthday(new Date());

        list.add(user);
        list.add(user1);


        return list;
    }

       /*
    *
    * 总结:
         接收日期参数 使用注解 @DateTimeFormat(pattern = "yyyy-MM-dd")
         响应日期参数 使用注解  @JSONField(format = "yyyy-MM-dd")


       * 注意: 使用fastjson 必须要 配置 转换器

     */

}

7.4 springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">


    <!--ioc扫描器-->
    <context:component-scan base-package="com.bjpowernode.web"/>
    <!--mvc 注解驱动-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!-- <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> -->
            <bean class="com.bjpowernode.fastjson.convert.JsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!--处理静态资源-->
    <mvc:default-servlet-handler/>
    <!--视图解析器,配置模板-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

7.5 JsonHttpMessageConverter.java

package com.bjpowernode.fastjson.convert;

import java.io.IOException;

import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

public class JsonHttpMessageConverter extends FastJsonHttpMessageConverter{
    @Override
    protected void writeInternal(Object obj, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {
        // TODO Auto-generated method stub
        JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd";
        JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);
        super.writeInternal(obj, outputMessage);

    }
}

7.6 前端页面

src\main\webapp
index3.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/fast/index3/" method="post">
    姓名:<input type="text" name="name"/><br/>
    年龄:<input type="text" name="age"/><br/>
    生日:<input type="date" name="birthday"/><br/>
    <input type="submit" value="注册"/>
</form>
</body>
</html>

7.6.5 以下是原理讲解

1.后端返回给前端的数据

1.1 返回值是对象 (xml和@JSONField)

在这里插入图片描述
在这里插入图片描述

1.2 返回值是JSON格式的字符串(xml)

在这里插入图片描述
在这里插入图片描述

1.3 返回值是集合(xml和@JSONField)

在这里插入图片描述
在这里插入图片描述

2.后端接收前端的数据

2.1 接收单个日期参数(xml和@DataTimeFormat)

在这里插入图片描述

在这里插入图片描述

2.2 封装了日期参数的对象 (xml和@DateTimeFormat)

在这里插入图片描述
在这里插入图片描述

3.小结

返回值是对象和集合都用xml和@JSONField
返回值是JSON格式的字符串用xml
后端接收参数都用xml和@DataTimeFormat

八、文件上传下载

8.1 文件上传

8.1.1 pom.xml

在这里插入图片描述
pom,xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjpowernode</groupId>
    <artifactId>10-fileUploadAndDownload</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <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>
        <spring.version>5.2.0.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--springmvc-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.7</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!--tool-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>

        <!--log-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.12</version>
        </dependency>

        <!-- 文件上传相关依赖jar 开始 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>
        <!-- 文件上传相关依赖jar 结束 -->

    </dependencies>


</project>

8.1.2 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>

    <!-- 编码过滤器 -->
    <filter>
        <filter-name>charsetFilter</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>charsetFilter</filter-name>
        <!-- 只对springmvc处理的请求进行编码过滤 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--springmvc的配置的文件的位置
              classPath: 字节码的输出路径
             -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>



</web-app>

8.1.3.1 SpringMVC.xml

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">


    <!--ioc扫描器-->
    <context:component-scan base-package="com.bjpowernode.web"/>
    <!--mvc 注解驱动-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!--解决中文乱码问题 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!--处理静态资源-->
    <mvc:default-servlet-handler/>
    <!--视图解析器,配置模板-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--配置上传文件的解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"/>
    </bean>
</beans>

8.1.3.2 SpringMVC.xml(Controller写法三对应的)

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">

    <!--ioc扫描器-->
    <context:component-scan base-package="com.bjpowernode.controller"/>

    <!--注解驱动
    表示配置最新的处理器映射器,处理器适配器,视图解析器
    -->
    <mvc:annotation-driven >

    </mvc:annotation-driven>

    <!--处理静态资源-->
    <mvc:default-servlet-handler/>

    <!--视图解析器 显示的拿出来-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--配置文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--上传每个文件大小的限制-->
        <property name="maxUploadSizePerFile" value="#{1*1024*1024}"/>
        <!--上传文件的总大小的限制-->
        <property name="maxUploadSize" value="#{10*1024*1024}"/>
    </bean>
</beans>

8.1.4.uploadPage.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    姓名:<input type="text" name="name"/><br/>
    上传文件:<input type="file" name="headImg"><br/>
    <input type="submit" value="注册"/>
</form>
</body>
</html>

8.1.5.1 controller层(写法一)

package com.bjpowernode.web.controller;

import cn.hutool.core.img.ImgUtil;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.awt.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;


@Controller
@RequestMapping("/upload")
public class UploadController {

    @RequestMapping("")
    @ResponseBody
    /*
     * 变量的名称必须和 表单中的name属性的名称一致
     * */
    public String upload(MultipartFile headImg,String name){
        System.out.println("name = " + name);
        /**
         * 文件上传考虑的问题:
         *   文件上传的路径的问题
         *   上传文件的大小问题
         *   上传文件的类型
         *   上传文件的名称设置
         *
         * 问题解决方案:
         *    文件上传的路径的问题  (1.项目的根目录下面(使用少),2.使用第三方的图片服务器(阿里,七牛云...))
         *    上传文件的大小问题   通过上传的文件可以获取到文件的真实大小,可以达到限制的目的
         *    上传文件的类型问题   通过上传的文件可以获取到文件的类型。进而进行判断
         *    上传文件的名称问题   通过时间戳 或者 UUID 来随机生成文件的新的名称达到唯一的目的
         *
         */

        String originalFilename = headImg.getOriginalFilename();
        System.out.println("originalFilename = " + originalFilename);

        // 提取文件的后缀名
        String ext = originalFilename.substring(originalFilename.lastIndexOf("."));
        // 随机生成一个字符串 和 文件的后缀名 拼接 生成新的文件名
        String newFileName = UUID.randomUUID().toString() + ext;

        // 上传的文件夹路径
//        String dirPath = "H:\\POWER_NODE\\Projects\\ClassroomTeaching\\SpringMVCProjects\\10-fileUploadAndDownload\\src\\main\\webapp\\upload\\";
//        String uploadPath = dirPath + newFileName;

//        String dirPath = "H:\\POWER_NODE\\Projects\\ClassroomTeaching\\SpringMVCProjects\\10-fileUploadAndDownload\\src\\main\\webapp\\upload";
//        String uploadPath = dirPath + "/"+newFileName;

        String dirPath = "H:\\POWER_NODE\\Projects\\ClassroomTeaching\\SpringMVCProjects\\10-fileUploadAndDownload\\src\\main\\webapp\\upload";
        String uploadPath = dirPath + "\\"+newFileName;


        Font font = new Font("微软雅黑", Font.BOLD, 15); // 字体的属性设置

        try {
            // 文件上传的方法
            ImgUtil.pressText(headImg.getInputStream(), new FileOutputStream(uploadPath), "我是水印", Color.RED, font, 1, 1, 0.5f);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("headImg.getSize() = " + headImg.getSize());

        String contentType = headImg.getContentType();
        System.out.println("contentType = " + contentType);

        return "文件上传成功";
    }

}

上传效果
在这里插入图片描述

8.1.5.2 controller层(写法二)

package com.bjpowernode.web;

import cn.hutool.core.img.ImgUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.awt.*;
import java.io.*;
import java.util.UUID;

@Controller
@RequestMapping("/upload")
public class FileUploadController {

    @RequestMapping("/file")
    @ResponseBody
    public String fileUpload(MultipartFile image){

        System.out.println("image.getOriginalFilename() = " + image.getOriginalFilename());


        /*
        * 限制问题(类型限制,大小限制)
        * 名称问题 (名称重复)
        * 路径问题 (保存到哪里,保存到 图片服务器,保存到项目的根路径下面)
        *
        * */
        String contentType = image.getContentType();
        System.out.println("contentType = " + contentType);
        if (!contentType.startsWith("image/")){
             return "图片格式不对";
        }
        // 字节
        long size = image.getSize();
        if (size>1000000) {
            return "上传的图片太大";
        }

        String filename = image.getOriginalFilename();
        String ext = filename.substring(filename.lastIndexOf("."));
        //  文件重新命名
        String newFileName = UUID.randomUUID().toString() + ext;


        String path = "E:\\apache-tomcat-9.0.65\\webapps\\ROOT\\"+newFileName;
//
//        try {
//            InputStream inputStream = image.getInputStream();
//            FileOutputStream fileOutputStream = new FileOutputStream(new File(path));
//            int len = 0;
//            byte[] buffer = new byte[1024];
//            while ((len=inputStream.read(buffer))!=-1){
//                 fileOutputStream.write(buffer,0,len);
//                 fileOutputStream.flush();
//            }
//            fileOutputStream.close();
//            inputStream.close();
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }

        Font font = new Font("微软雅黑", Font.BOLD, 15); // 字体的属性设置
        // 文件上传的方法
        try {
            // 使用了hutool工具类
            ImgUtil.pressText(image.getInputStream(), new FileOutputStream(path), "我是水印", Color.RED, font, 1, 1, 0.5f);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


        // 上传成功后的图片的路径
        return "http://localhost:90/"+ newFileName;
    }
}

8.1.5.3 controller层(写法三)

package com.bjpowernode.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
@RequestMapping("/upload")
public class UploadController {
    @RequestMapping("/file")
    @ResponseBody
    public String upload(MultipartFile image){
        String originalFilename = image.getOriginalFilename();
        System.out.println("originalFilename = " + originalFilename);
        System.out.println("image.getSize() = " + image.getSize());
        System.out.println("image.getContentType() = " + image.getContentType());

        if(!image.getContentType().startsWith("image/")){
            return "上传的文件类型错误";
        }

        String ext = originalFilename.substring(originalFilename.indexOf("."));
        String fileNewName = UUID.randomUUID().toString() + ext;

        // 上传到云服务器  上传成功以后,云服务返回,图片资源的真实路径 , http://asdsafas
        // 上传到项目的根路径下面,(跟着项目走)
        String path="D:\\HHH\\Desktop\\05_fileUploadAndFileDownload\\src\\main\\webapp\\upload";
        try {
            image.transferTo(new File(path,fileNewName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
}

8.2 文件下载

8.2.1 pom.xml

在这里插入图片描述
部分代码

<dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

全部代码

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjpowernode</groupId>
    <artifactId>10-fileUploadAndDownload</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <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>
        <spring.version>5.2.0.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--springmvc-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.7</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!--tool-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>

        <!--log-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.12</version>
        </dependency>

        <!-- 文件上传相关依赖jar 开始 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>
        <!-- 文件上传相关依赖jar 结束 -->


        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>


    </dependencies>

8.2.2 downloadPage.html

src\main\webapp
downloadPage.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

下载功能: <br/>
<a href="/download?fileName=美女.webp">美女.webp</a> <br/>
<a href="/download?fileName=美女.zip">美女.zip</a> <br/>
<a href="/download?fileName=美女.rar">美女.rar</a> <br/>
</body>
</html>

8.2.3 供用户下载的资源

在这里插入图片描述

8.2.4 controller层

DownloadController.java

package com.bjpowernode.web.controller;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

@Controller
@RequestMapping("/download")
public class DownloadController {
    @RequestMapping
    public String download(String fileName, HttpServletResponse response){
        //设置响应类型 通知浏览器 不要打开
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

        // 通过设置头信息 不让浏览器把图片的名称 后缀名进行修改
        String name = null;
        try {
            name = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println("编码后的名字:"+name);
        response.setHeader("Content-Disposition", "attachment; filename="+name);

        String dirPath = "H:\\POWER_NODE\\Projects\\ClassroomTeaching\\SpringMVCProjects\\10-fileUploadAndDownload\\src\\main\\webapp\\download\\";
        String resourcePath = dirPath + fileName;
        File imageFile = new File(resourcePath);
        if(imageFile.exists()){
            try {
                FileInputStream inputStream = new FileInputStream(resourcePath);
                ServletOutputStream outputStream = response.getOutputStream();
                int len = 0;
                byte[] buffer = new byte[1024];
                while((len = inputStream.read(buffer))!=-1){
                    outputStream.write(buffer,0,len);
                    outputStream.flush();
                }
                outputStream.close();
                inputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return "下载成功";
    }
}

九、拦截器

9.1 概念说明

SpringMVC提供HandlerInteceptor接口,这个接口用于拦截处理具体的Handler中的方法,在具体的Handler中的方法执行前后及返回视图之间都可以进行相关扩展操作。

9.1.1 如何使用拦截器

9.1.1.1 创建类实现HandlerInteceptor接口
package com.bjpowernode.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description: 自定义拦截器
 */
public class MyInterceptor implements HandlerInterceptor {
    /**
     * 在执行具体的Handler中的方法前执行
     * @param request  当前的请求对象
     * @param response  当前的响应对象
     * @param handler   具体的处理器中将要执行的方法
     * @return   boolean  如果 返回 true 则执行Handler中的方法   false 则 不执行handler中的方法
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("我是拦截器中preHandle 方法");
        return true;
    }
    /**
     *  在具体的Handler中的方法执行完成 但是没有做具体的视图解析操作
     * @param request  当前 请求对象
     * @param response  当前响应对象
     * @param handler 具体的处理器中将要执行的方法
     * @param modelAndView 具体的处理器中将要执行的方法 返回的结果
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("我是拦截器中postHandle 方法");
        //在具体的解析之前  修改视图模型中数据
        modelAndView.addObject("name","韩梅梅");
    }
    /**
     *  完成了视图解析后 整个方法执行完成调用的方法 在finally中调用 或者出现异常也会调用
     * @param request   当前请求对象
     * @param response  当前响应对象
     * @param handler   具体的处理器中将要执行的方法
     * @param ex         具体的处理器中抛出的异常
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("我是拦截器中afterCompletion 方法");
        System.out.println(ex.getMessage());
        request.setAttribute("msg","网管去火星了!");
        request.getRequestDispatcher("/500.jsp").forward(request,response);
    }
}
9.1.1.2 配置拦截器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">
    <!-- 开启组件扫描 -->
    <!-- 扫描所有处理器 放入到处理器映射器中 -->
    <context:component-scan base-package="com.bjpowernode.controller" />
    <!-- 开启 mvc注解 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!-- 文件上传的解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
        <!--<property name="maxUploadSize" value="1"></property>-->
    </bean>
    <!-- 配置springmvc的拦截器 -->
    <mvc:interceptors>

        <mvc:interceptor>
            <!-- 拦截器的资源路径  /** 拦截所有  ** 表示多层目录 -->
            <mvc:mapping path="/**"/>
            <!-- 不拦截的资源路径 -->
            <mvc:exclude-mapping path="/user/page.do"/>
            <!-- 自定义的拦截器 -->
            <bean id="myInterceptor" class="com.bjpowernode.interceptor.MyInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

注意:
1.在拦截器中,最先执行preHandle,然后执行Handler中具体的方法,再然后执行postHandle和afterCompletion。preHandle就是前置的拦截的方法,返回如果为true,则执行处理器中的方法,如果为false则不执行处理器中的方法。postHandle是在Handler中具体的方法执行完成,但是没有交给视图解析器之前执行,afterCompletion在视图解析器完成了视图解析之后执行的。
2.拦截器是拦截器的方法,被DispatcherServlet代理调用的方法,如果请求的不是Handler,拦截器是不会拦截的。index.jsp由于是由tomcat默认的servlet进行返回的,不会执行DispatcherServlet中的doDispatch,那么拦截器无法进行拦截。

9.1.2 Interceptor和Filter的区别

Filter是Java Web的规范,拦截的是请求,任何JavaWeb项目都可以有Filter,但是Interceptor是SpringMVC提供的一套规范HandlerInterceptor,只适用SpringMVC自身,并且只能对DispatherServlet处理器的请求生效,拦截的方法。从范围上说,任何JavaWeb项目都有Filter,但是未必有Interceptor。

9.2 案例实操

9.2.1 controller层

com.bjpowernode.web.controller
HelloController,java

package com.bjpowernode.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/hello")
public class HelloController {
    @RequestMapping
    @ResponseBody
    public String index(){
        return "index";
    }
}

9.2.2 拦截器类

com.bjpowernode.web.interceptor
MyInterceptor.java

package com.bjpowernode.web.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("come in");
        return false;
    }
}

9.2.3 配置文件springMVC.xml

在这里插入图片描述

部分代码

<!--配置springmvc的拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--拦截器的资源路径 /** 拦截所有 ** 表示多层目录-->
            <mvc:mapping path="/**"/>
            <!--不拦截的资源路径-->
            <mvc:exclude-mapping path="/login"/>
            <mvc:exclude-mapping path="/register"/>
            <!--自定义的拦截器-->
            <bean class="com.bjpowernode.web.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

全部代码
springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://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">


    <!--ioc扫描器-->
    <context:component-scan base-package="com.bjpowernode.web"/>
    <!--mvc 注解驱动-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!--解决中文乱码问题 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!--处理静态资源-->
    <mvc:default-servlet-handler/>
    <!--视图解析器,配置模板-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--配置上传文件的解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"/>
    </bean>

    <!--配置springmvc的拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--拦截器的资源路径 /** 拦截所有 ** 表示多层目录-->
            <mvc:mapping path="/**"/>
            <!--不拦截的资源路径-->
            <mvc:exclude-mapping path="/login"/>
            <mvc:exclude-mapping path="/register"/>
            <!--自定义的拦截器-->
            <bean class="com.bjpowernode.web.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

9.3 拦截器拦截静态资源

index.html
在这里插入图片描述

<url-pattern>/</url-pattern>
在这里插入图片描述
浏览器访问http://localhost:8080/index.html 被拦截器拦截了
在这里插入图片描述

9.3.1 <url-pattern>*.do</url-pattern>

在这里插入图片描述

浏览器访问http://localhost:8080/index.html 没有拦截器
在这里插入图片描述

9.3.2 在Spring-mvc.xml配置文件中,配置要放行的静态资源

<url-pattern>*.do</url-pattern>被淘汰了,还是用<url-pattern>/</url-pattern>
web.xml中
在这里插入图片描述

开启拦截
在这里插入图片描述
在这里插入图片描述
浏览器访问http://localhost:8080/index.html 被放行了
在这里插入图片描述

9.4 拦截器链(多个拦截器)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在浏览器中访问localhost:8080/hello/list
在这里插入图片描述
在这里插入图片描述

十、统一异常处理器

10.1 概念理论

在spring中,相对完善的异常处理器机制,spring可以自己定义处理异常的规则,这种处理异常规则的程序,就被称之为异常处理器。其实,异常处理器就是对controller的增强,因为异常是向上抛,controller调用service,service调用mapper,controller属于最上层,所以最终异常都会汇集到controller。因此,spring提供了@ControllerAdvice注解,表示对controller增强类。并且还提供了@ExceptionHandler这个注解,当发生异常时,该注解修饰的方法就会执行。
在实际开发中,异常主要分为两类:
1.系统异常,JDK中定义的异常
2.业务异常,开发者自己定义的异常
一般是将系统异常转化为业务异常,开发者只处理业务异常。使用try…catch…将代码包裹起来,在catch中抛出自定义的异常,这种方案就是将系统异常转化为业务异常。因为很多数据操作,事务需要异常进行数据回滚。

10.2 案例实操

10.2.1 最终项目结构

在这里插入图片描述

10.2.2 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjpowernode</groupId>
    <artifactId>12-exceptionorproject</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <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>
        <spring.version>5.2.0.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--springmvc-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.7</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!--tool-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>

        <!--log-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.12</version>
        </dependency>

        <!-- 文件上传相关依赖jar 开始 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>
        <!-- 文件上传相关依赖jar 结束 -->


        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.3</version>
        </dependency>


    </dependencies>


</project>
package com.bjpowernode.service;

public interface UserService {
    void login(String username,String pwd);
}

10.2.3 controller层 和 前段页面的演变过程

login.html
在这里插入图片描述
LoginController.java
在这里插入图片描述
login.html
在这里插入图片描述
LoginController.java
在这里插入图片描述
login.html
在这里插入图片描述
controller层引入JSONResult

10.2.4 JSONResult.java

com.bjpowernode.web
JSONResult.java

package com.bjpowernode.web;

import lombok.Getter;

@Getter
public class JSONResult {
    private boolean success = true;
    private String msg;

    public JSONResult mark(String msg){
        this.success = false;
        this.msg =msg;
        return this;
    }
}

10.2.5 controller层

controller层引入JSONResult
在这里插入图片描述
controller层引入service

10.2.6 service层

接口
UserService.java

package com.bjpowernode.service;

public interface UserService {
    void login(String username,String pwd);
}

实现类
UserServiceImpl.java

package com.bjpowernode.service.impl;

import com.bjpowernode.exception.MyLogicException;
import com.bjpowernode.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

   @Override
   public void login(String username, String pwd) {
       if(username == null || username.equals("")){
            throw new RuntimeException("用户名不能为空");
       }
       if(pwd == null || pwd.equals("")){
            throw new RuntimeException("密码不能为空");
        }
        // 查询数据库

    }
}

10.2.7 自定义异常类

引入自定义异常类
com.bjpowernode.exception
MyLogicException.java

package com.bjpowernode.exception;

public class MyLogicException extends RuntimeException{
    public MyLogicException(String msg){
        super(msg);
    }
}

10.2.8.统一异常处理器类

com.bjpowernode.web
MyAdviceController.java

package com.bjpowernode.web;

import com.bjpowernode.exception.MyLogicException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

// 统一异常处理器 : 项目中所有报的运行时异常 都会 到这里
/*
* Spring专门为解决异常问题,开发了针对Controller层的注解
* 注解的核心就是 Spring-AOP
*/
/*@ControllerAdvice //advice通知*/
@RestControllerAdvice /*相当于@ControllerAdvice+@ResponseBody*/
public class MyAdviceController {

    /**
     * 拦截什么异常:运行时异常
     *  @ExceptionHandler 异常处理器 切入点表达式 @PointCut()
     * @param e
     * @return
     */
    // 匹配异常 当遇到异常的时候,返回给页面 jsonResult
    @ExceptionHandler(MyLogicException.class)
    /*有@RestControllerAdvice注解@ResponseBody可以省略*/
   /* @ResponseBody*/
    public JSONResult myLogicException(MyLogicException e){
        JSONResult jsonResult = new JSONResult();
        return jsonResult.mark(e.getMessage());

    }

//    // 兜底异常
//    @ExceptionHandler(RuntimeException.class)
//    @ResponseBody
//    public JSONResult runtimeException(RuntimeException e){
//        JSONResult jsonResult = new JSONResult();
//        return jsonResult.mark(e.getMessage());
//
//    }

    // 兜底异常
    @ExceptionHandler(RuntimeException.class)
    public String runtimeException(RuntimeException e){
       e.printStackTrace();
        System.out.println("运行时异常");
        return null;

    }
}

10.2,9 controller层最终版

在这里插入图片描述

package com.bjpowernode.web.controller;

import com.bjpowernode.service.UserService;
import com.bjpowernode.web.JSONResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

//@Controller
@RestController/*相当于@Controller+@ResponseBody*/
@RequestMapping("/user")
public class LoginController {

    @Autowired
    private UserService userService;

    // 统一异常
    // 判断参数,和 处理参数 应当由业务层处理
    //当没有遇到异常的时候,返回给页面 jsonResult
    @RequestMapping("/login")
    /*@ResponseBody*/
    public JSONResult login(String username, String pwd) {
        JSONResult jsonResult = new JSONResult();
        userService.login(username, pwd);
        return jsonResult;
    }


//    // 判断参数,和 处理参数 应当有业务层处理
//    //当没有遇到异常的时候,返回给页面 jsonResult
//    @RequestMapping("/login")
//    @ResponseBody
//    public JSONResult login(String username,String pwd){
//
//        JSONResult jsonResult = new JSONResult();
//
//        try {
//            userService.login(username,pwd);
//        } catch (Exception e) {
//            e.printStackTrace();
//            return jsonResult.mark(e.getMessage());
//        }
//
//        return jsonResult;
//    }


//    // 判断参数,和 处理参数 应当有业务层处理
//    //当没有遇到异常的时候,返回给页面 jsonResult
//    @RequestMapping("/login")
//    @ResponseBody
//    public JSONResult login(String username,String pwd){
//
//        JSONResult jsonResult = new JSONResult();
//
//        if (username == null || username.equals("")){
//            return jsonResult.mark("用户名不能为空");
//        }
//        if(pwd == null|pwd.equals("")){
//            return jsonResult.mark("密码不能为空");
//        }
//        return jsonResult;
//    }

//    @RequestMapping("/login")
//    @ResponseBody
//    public String login(String username,String pwd){
//
//
//      if (username == null || username.equals("")){
//          return "用户名不能为空";
//      }
//      if(pwd == null|pwd.equals("")){
//          return "密码不能为空";
//      }
//        return "登录成功";
//    }

//    @RequestMapping("/login")
//    @ResponseBody
//    public String login(String username,String pwd){
//        System.out.println("username = " + username);
//        System.out.println("pwd = " + pwd);
//        return "登录成功";
//    }
}

十一、Restful风格

架构风格 请求地址的展示形式
http://lcoalhost/login?name=tony&pwd=123 这样形式 不好,暴露了参数信息

http://lcoalhost/tony/login/123 这是个地址看不出谁是参数 Restful

11.1 Http协议设计的初衷

HTTP协议在设计时,期望使用一个URL表示一个资源。然后,根据不同的动作:GET、POST、PUT、DELETE等等表示对一个资源的各种操作。
如:
获取这个资源就使用GET,
修改这个资源PUT,
删除这个资源用DELETE,
创建这个资源使用POST。
但是在实际使用中,多个URL表示一个资源,例如:新增用户: addUser,修改用户:updateUser,删除用户:deleteUser.,查询一个用户:getUser.。这时候,出现一个资源存在多个URL。在一定程度声,违背了HTTP协议的设计初衷,并且命名也是个问题。

11.2 Restful设计思想

1.使用一个URL表示一种资源
2.客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源
3.通过操作资源的表现形式来操作资源

11.3 案例实操

LoginController.java

package com.bjpowernode.web.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

//@Controller
@RequestMapping("/user")
//@ResponseBody//让当前类中的所有方法都生效,返回json格式的数据
//@Controller + @ResponseBody = @RestController
@RestController
public class LoginController {

    /*
     * @PathVariable 注解 只适用于 restfull 风格中 传递的参数,
     * 并且 要求 ,接收的变量命名要尽量和 参数名称 一致 ,如果不一致 必须使用注解中的value 属性来指定
     * */
    @RequestMapping("/{pwd}/{name}")
//    @ResponseBody
    public String login(@PathVariable String name, @PathVariable String pwd){
        System.out.println("name = " + name);
        System.out.println("pwd = " + pwd);
        return "登录成功";
    }

    @RequestMapping("/save/{pwd}/{name}")
//    @ResponseBody
    public String login2(@PathVariable String name, @PathVariable String pwd){
        System.out.println("name = " + name);
        System.out.println("pwd = " + pwd);
        return "登录成功";
    }

    @RequestMapping("/{pwd}/save/{name}")
    public String login3(@PathVariable  String name, @PathVariable String pwd){
        System.out.println("name = " + name);
        System.out.println("pwd = " + pwd);
        return "登录成功";
    }

    @GetMapping
//    @ResponseBody
    public String select(){
        return "查询操作";
    }

    @PutMapping
//    @ResponseBody
    public String update(){
        return "更新操作";
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/85563.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!