springMVC基本使用(涛哥版)

文章目录

二、SpringMVC概述

  • Spring MVC是由Spring官方提供的基于MVC设计理念的web框架
  • Spring MVC是基于Servlet封装的用于实现MVC控制的框架,实现前端和服务端的交互。

2.1 SpringMVC优势

  • 严格遵守了MVC分层思想
  • 采用了松耦合、插件式结构;相比较于我们封装的BaseServlet以及其他的一些MVC框架来说更灵活、更具扩展性
  • SpringMVC是基于Spring的扩展、提供了一套完善的MVC注解
  • SpringMVC在数据绑定、视图解析都提供了多种处理方式,可灵活配置
  • SpringMVC对RESTful URL设计方法提供了良好的支持

2.2 SpringMVC本质工作

  • 接收并解析请求
  • 处理请求
  • 数据渲染、响应请求

三、SpringMVC框架部署

3.1 基于Maven创建一个Web工程

img

img

img

img

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WNXhhZUP-1651847342866)(https://note.youdao.com/yws/public/resource/7d8c16ef13900aefaa5e948a417c2c48/xmlnote/110FEEB45EF04A49A19CAE0ED788034F/72)]

3.2 添加SpringMVC依赖

  • spring-context
  • spring-aspects
  • spring-jdbc
  • spring-web
  • spring-webmvc
  • spring-junit
    <spring.version>5.2.13.RELEASE</spring.version>
</properties>

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

<dependencies/>
<?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.liguoqing</groupId>
    <artifactId>springmvc-demo2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <spring.version>5.2.13.RELEASE</spring.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</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>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>
</project>

3.3 创建SpringMVC配置文件

  • 在resource目录下创建名为spring-servlet.xml 文件
  • 添加MVC命名空间

spring-servlet.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:aop="http://www.springframework.org/schema/aop" 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      http://www.springframework.org/schema/context/spring-context.xsd      http://www.springframework.org/schema/aop      http://www.springframework.org/schema/aop/spring-aop.xsd      http://www.springframework.org/schema/mvc      http://www.springframework.org/schema/mvc/spring-mvc.xsd">   
    <!--    声明使用注解配置-->
    context:annotation-config/    <!--    声明Spring工厂注解的扫描范围-->
    <context:component-scan base-package="com.liguoqing"/>    
    <!--    声明mvc使用注解驱动-->    
   < mvc:annotation-driven/>?
</beans>

3.4 在web.xml中配置SpringMVC的前端控制器

SpringMVC提供了一个名为DispatcherServlet的类(SpringMVC前端控制器),用于拦截用户请求交由SpringMVC处理

webapp/WEB-INF/web.xml

1

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet.xml</param-value>
        </init-param>
        
        <!-- 服务器启动时 创建DispatcherServlet  而不是第一次访问时创建-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>  <!--    /* 拦截所有的HTTP请求,包括.jsp的请求,都做为控制器类的请求路径来处理--> <!--    / 拦截所有的HTTP请求,但不包括.jsp的请求,但不会放行静态资源请求,html/js/css/图片-->
</web-app>

三、SpringMVC框架使用

3.1

在SpringMVC中,我们把接收用户请求,处理用户请求的类称之为Controller(控制器)

3.1.1 创建控制器

  • 创建一个名为 com.liguoqing.controllers 的包(包需要在Spring注解扫描的范围内)
  • 创建一个类(无需做任何的继承和实现)
  • 在类上添加 @Controller 注解声明此类为SpringMVC的控制器
  • 在类上添加 @RequestMapping(“/url”) 声明此控制器类的请求url

package com.liguoqing.controllers; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping(“/book”) public class BookController { }

3.1.2 在控制器类中定义处理请求的方法

  • 在一个控制器类中可以定义多个方法处理不同的请求
  • 在每个方法上添加 @RequestMapping(“/url”) 用于声明当前方法请求的url

3.1.3 访问

  • http://localhost:8081/springmvc_demo22_war_exploded/book/add
  • http://localhost:8081/springmvc_demo22_war_exploded/book/list

3.2 静态资源配置

静态资源:就是项目中的HTML、CSS、JS、图片等

3.2.1 /* 和 / 区别

<!--    /* 拦截所有的HTTP请求,包括.jsp的请求,都做为控制器类的请求路径来处理--> <!--    / 拦截所有的HTTP请求,但不包括.jsp的请求,但不会放行静态资源请求(html/js/css/图片)-->
<servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

3.2.2 静态资源放行配置

  • 在springMVC的配置文件中,添加如下静态资源放行的配置

spring-servlet.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:aop="http://www.springframework.org/schema/aop" 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       http://www.springframework.org/schema/context/spring-context.xsd       http://www.springframework.org/schema/aop       http://www.springframework.org/schema/aop/spring-aop.xsd       http://www.springframework.org/schema/mvc       http://www.springframework.org/schema/mvc/spring-mvc.xsd">      
    <!--    声明使用注解配置-->
    context:annotation-config/     
    <!--    声明Spring工厂注解的扫描范围-->
    <context:component-scan base-package="com.liguoqing"/>    
    <!--    声明mvc使用注解驱动-->     mvc:annotation-driven/
    
    ------------------------------------------------ <!--放行资源-->
    <mvc:resources mapping="/css/" location="/css/"/>
    <mvc:resources mapping="/pages/" location="/pages/"/>
    <mvc:resources mapping="/imgs/" location="/imgs/"/>
    <mvc:resources mapping="/js/" location="/js/"/>
</beans>
    ------------------------------------------------ <!--放行资源-->
    <mvc:resources mapping="/css/" location="/css/"/>
    <mvc:resources mapping="/pages/" location="/pages/"/>
    <mvc:resources mapping="/imgs/" location="/imgs/"/>
    <mvc:resources mapping="/js/" location="/js/"/>

mvc:default-servlet-handler/

dispatcherservlet处理不了静态资源 处理会报错,报完错后给

defaultservlet处理 default-servlet-handler 静态资源

先交给dispatcherservlet处理然后交给defaultservlet

 <!--当springmvc处理不了静态资源的时候才会启用  默认servlet-handler 来处理静态资源-->
<mvc:default-servlet-handler/>

要设置
<!--    将注解功能启动-->
    <mvc:annotation-driven/>  不开启这个注解驱动,所有的注解都会没有用,会默认被默认的servlet处理

3.3 前端提交数据到控制器

3.3.1 表单提交

表单提交:输入框需要提供name属性,springMVC控制器是通过name属性取值的

<%--   Created by IntelliJ IDEA.   User: Administrator   Date: 2022/1/15   Time: 21:33   To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title></head>
<body><h3>添加图书</h3>
<form action="book/add" method="post"><p>图书名称:<input type="text"></p>
    <p>图书作者:<input type="text"></p>
    <p>图书价格:<input type="text"></p>
    <p><input type="submit" value="提交"></p></form>
</body>
</html>

3.2.2 URL提交

URL提交:<a href="book/add?bookName=java">url提交<a/>

3.3.3 AJAX提交

AJAX提交:请求行、请求头、请求体都可以用来传值


<h3>AJAX提交</h3> <input type="button" value="ajax提交"/>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">    $("#btn1").click(function () {
    var obj = {};
    obj.bookName = "Java";
    obj.bookAuthor = "张三";
    obj.bookPrice = 3.33;
    $.ajax({
        url: "book/add",
        type: "post",
        headers: {},
        contentType: "application/json",
        data: obj,
        success: function (res) {
            console.log(res);
        }
    });
}); </script>

3.3.4http协议

image-20220417161612720

3.4 控制器中接收前端提交的数据

3.4.1 请求行传值

  • 表单提交 method=“get”
  • URL提交
  • $.ajax请求的url传值

<h3>AJAX提交</h3> <input type="button" value="ajax提交"/>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">    $("#btn1").click(function () {
    var obj = {};
    obj.bookName = "Java";
    obj.bookAuthor = "张三";
    obj.bookPrice = 3.33;
    $.ajax({
    url:这里拼接url,把参数放url就是请求行传值,
    type:"post",
    headers:{
    },
    contentType:"application/json",
    data:obj,
    success:function (res){
        console.log(res);
    }
});
}); </script>
  • . p o s t ( ) / .post()/ .post()/.get() 中的{}传值

@RequestParam 注解用于接收请求行传递的数据

  • 前端提交数据
<h3>表单提交</h3>
<form action="book/add" method="post"><p>图书名称:<input type="text" name="name"></p>
    <p>图书作者:<input type="text" name="author"></p>
    <p>图书价格:<input type="text" name="price"></p>
    <p><input type="submit" value="提交"></p></form>
  • 控制器接收数据
package com.liguoqing.controllers;

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

@Controller
@RequestMapping("/book")
public class BookController { //       <form action="book/add" method="post"> //        <p>图书名称:<input type="text" name="name"></p> //        <p>图书作者:<input type="text" name="author"></p> //        <p>图书价格:<input type="text" name="price"></p> //        <p><input type="submit" value="提交"></p> //    </form>    /接收请求行数据/  
    @RequestMapping("/add")
    public void add(@RequestParam("name") String a, @RequestParam("author") String b, @RequestParam("price") double c) {
        System.out.println("~book add");
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }
}

注意:

如果控制器方法中接收数据的参数名与请求行传值的key是一致的,则@RequestParam注解可以省略

public static void main(String[]args){
@RequestMapping("/add")
    public void add(String name,String author,double price){
        System.out.println("~book add");
        System.out.println(name);
        System.out.println(author);
        System.out.println(price);
    }
        }

3.4.2 请求头传值

  • $.ajax 封装请求头数据
    $.ajax({
        url: "book/add",
        type: "post",
        headers: {这里请求头传值},
        contentType: "application/json",
        data: obj,
        success: function (res) {
            console.log(res);
        }
    });

演示代码:(这里的请求头里如果写中文暂时是有问题的)

@RequestHeader 用于接收请求头传递的数据

@RequestMapping("/list")
public void list(@RequestHeader("token") String token){ 
    System.out.println(token);  
    System.out.println("~book list"); } 

<h3>AJAX提交</h3> <input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">    $("#btn1").click(function () {
    console.log("进入方法");
    var obj = {};
    obj.bookName = "Java";
    obj.bookAuthor = "张三";
    obj.bookPrice = 3.33;
    console.log("obj");
    $.ajax({
        url: "book/list",
        type: "post",
        headers: {token: "Eqeqeq"},  
// contentType:"application/json",
            // data:obj,
            success:function (res){
                console.log(res);
            }
        });
        console.log("结束");
    });
</script>

3.4.3 请求体传值

  • $.ajax 封装请求体数据
$.ajax({
    url:"book/add",
    type:"post",
    headers:{
        这里请求头传值
    },
    contentType:"application/json",
    data:{
        这里放请求体数据
    },
    success:function (res){
        console.log(res);
    }
});

@RequestBody 注解用于接收请求体传递的数据

  • 前端
<input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">    $("#btn1").click(function () {
    console.log("进入方法");
    var obj = {};
    obj.bookName = "pytone";
    obj.bookAuthor = "woshinidie";
    obj.bookPrice = 3.33;
    console.log("obj");
    $.ajax({
        url: "book/update",
        type: "post",            // headers:{
            //     token:"Eqeqeq"
            // },
            contentType:"application/json",
            data: JSON.stringify(obj), //data的值为json格式字符串,  
            contentType:"application/json"
            success:function (res){
                console.log(res);
            }
        });
        console.log("结束");
    });
</script>

@RequestBody 将前端请 求提交的JSON格式数据转换成java对象,依赖jackson包

  • 导入jackson的依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>
  • 控制器

     @RequestMapping("/update")
    public void update(@RequestBody Book book){
        System.out.println("~~~~~book update");
        try{
            System.out.println(book);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    ----------------------------------
    //    @RequestMapping("/update")
    //    public void update(HttpServletRequest request){
    //        System.out.println("~~~~~book update");
    //        try{
               Servlet的处理方法: 使用request 的输入流接收请求体数据
    //            ServletInputStream is = request.getInputStream();
    //            StringBuffer stringBuffer = new StringBuffer();
    //            byte[] bs = new byte[100];
    //            int len = -1;
    //            while ((len = is.read(bs)) != -1){
    //                String s = new String(bs,0,len);
    //                stringBuffer.append(s);
    //            }
    //            System.out.println(stringBuffer.toString());
    //
    //        } catch (IOException e) {
    //            e.printStackTrace();
    //        }
    //    }
    

3.5 控制器响应前端请求

3.5.1 控制器响应同步请求

同步请求:form , 超链接

  • 处理同步请求的方法的返回类型定义为String或者ModelAndView,以实现页面的跳转

  • 返回类型为String: 为了视图处理

转发

@RequestMapping("/add")
public String add(@RequestParam("name") String a,
                        @RequestParam("author") String b,
                        @RequestParam("price") double c){
    System.out.println("~~~~~book add");
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);

    //如何挑战到指定的页面呢?
    return "/tips.jsp";
}

重定向

@RequestMapping("/add")
public String add(@RequestParam("name") String a,
                        @RequestParam("author") String b,
                        @RequestParam("price") double c){
    System.out.println("~~~~~book add");
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);

    //如何挑战到指定的页面呢?
    return "redirect:/tips.jsp";
}
  • 返回类型为ModelAndView:

转发

@RequestMapping("/add")
public ModelAndView add(@RequestParam("name") String a,
                        @RequestParam("author") String b,
                        @RequestParam("price") double c){
    System.out.println("~~~~~book add");
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
    //如何挑战到指定的页面呢?
    ModelAndView modelAndView = new ModelAndView("/tips.jsp");
    return modelAndView;
}

重定向

@RequestMapping("/add")
public ModelAndView add(@RequestParam("name") String a,
                        @RequestParam("author") String b,
                        @RequestParam("price") double c){
    System.out.println("~~~~~book add");
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
    //如何挑战到指定的页面呢?
    ModelAndView modelAndView = new ModelAndView("redirect/tips.jsp");
    return modelAndView;
}

3.5.2 控制器响应异步请求

SpringMVC处理ajax(页面不发生跳转的情况下发生的交互)

异步请求:ajax请求

使用response中的输出流进行响应

  • 控制器方法的返回类型为void,因为不需要跳转
  • 控制器方法添加HttpServletResponse response 参数
  • 在方法中通过response 获取输出流,使用流响应ajax请求
<input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">  
    $("#btn1").click(function () {
    console.log("进入方法");
    var obj = {};
    obj.bookName = "pytone";
    obj.bookAuthor = "woshinidie";
    obj.bookPrice = 3.33;
    console.log("obj");
    $.ajax({
        url: "book/update",
        type: "post",            
        // headers:{
            //     token:"Eqeqeq"
            // },
            contentType:"application/json",
            data: JSON.stringify(obj), //data的值为json格式字符串,  
            dateType:"json"//预设接收的数据类型 是json
            success:function (res){
                console.log(res);
            }
        });
        console.log("结束");
    });
</script>
@RequestMapping("/update")
public void update(@RequestBody Book book, HttpServletResponse response){
    System.out.println("~~~~~book update");
    try{
        System.out.println(book);

        //使用ObjectMapper将对象转换成json格式字符串
        String s = new ObjectMapper().writeValueAsString(book);

        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json");//定义一下方便前端进行解析
        PrintWriter out = response.getWriter();
        out.println();
        out.close();

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

直接在控制器方法返回响应的对象

  • 控制器方法的返回类型设置为响应给ajax请求的对象类型
  • 在控制器方法前添加一个 @ResponseBody 注解,将返回的对象转换成JSON格式返回给ajax请求
  • 如果一个控制器类中的所有方法都是响应ajax请求,则可以直接在控制器类前添加 @ResponseBody 注解
  • 响应的内容是一个 json 数组
@RequestMapping("/update")
@ResponseBody
public List<Book> update(){
    System.out.println("~~~~~book update");

    ArrayList<Book> books = new ArrayList<Book>();
    books.add(new Book(1,"我朝","嘿嘿",2.33));
    books.add(new Book(2,"到店","顶顶",2.33));
    return books;
}

3.5.3 控制器响应同步请求的数据传递

对于同步请求的转发响应,我们可以传递参数到转发的页面

  • 返回类型为String:
//1:在控制器方法中定义一个Model类型的参数
//2:在return页面之前,向model中添加键值对,添加的键值对就会被传递到转发的页面
@RequestMapping("/add1")
public String add1(@RequestParam("name") String a,
                        @RequestParam("author") String b,
                        @RequestParam("price") double c,
                        Model model){
    model.addAttribute("key1","value1");
    model.addAttribute("key1",new Book(1,"Java","老张",2.33));
    return "/tips.jsp";

}

//除了使用Model对象传值外还可以直接使用HttpServletRequest对象
@RequestMapping("/add1")
public String add1(@RequestParam("name") String a,
                        @RequestParam("author") String b,
                        @RequestParam("price") double c,
                        HttpServletRequest request){
    request.addAttribute("key1","value1");
    request.addAttribute("key1",new Book(1,"Java","老张",2.33));
    return "/tips.jsp";

}
  • 返回类型ModelAndView
@RequestMapping("/add2")
public ModelAndView add2(@RequestParam("name") String a,
                        @RequestParam("author") String b,
                        @RequestParam("price") double c){
    System.out.println("~~~~~book add");
    ModelAndView modelAndView = new ModelAndView("/tips.jsp");
    modelAndView.addObject("key1","value");
    modelAndView.addObject("key2",new Book(1,"Java","老张",2.35));
    return modelAndView;
}

3.6 解决中文乱码问题

3.6.1 前端编码

  • JSP页面
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
  • HTML页面
<meta charset="UTF-8">

3.6.2 服务器编码

  • tomcat/conf/server.xml

image-20220425203519171

 <Connector port="8081" protocol="HTTP/1.1"               connectionTimeout="20000"               redirectPort="8443" URIEncoding="UTF-8"/>

3.6.3 设置SpringMVC的编码方式

  • 在web.xml中配置SpringMVC编码过滤器的编码方式
<filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

四:SpringMVC的请求处理流程

4.1

SpringMVC 通过前端控制器(DispatcherServlet)拦截并处理用户请求的

img

4.2 SpringMVC的核心组件

  • DispatcherServlet 前端控制器,总控制器

  • 作用:接收请求,协同各组件工作,响应请求

  • HandlerMapping 处理器映射

  • 作用:负责根据用户请求的URL找到对应的Handler

    可以自定义配置 SpirngMVC提供多个处理器映射的实现,可以根据需要进行配置

  • HandlerAdapter 处理器适配器

  • 作用:根据HandlerMapping 解析用户请求后产生的调用链,通过适配器模式完成Handler的调用

  • Handler 处理器/控制器

  • 由工程师根据业务的需求进行开发

    作用:处理请求

  • ModelAndView 视图模型

  • 作用:用于封装处理器返回的数据以及响应的视图

    ModelAndView = Model + View

  • ViewResolver 视图解析器

  • 作用:对ModelAndView进行解析

    可以自定义配置 SpirngMVC提供多个视图解析器的实现,可以根据需要进行配置

  • View 视图

  • 作用:完成数据渲染

4.3 处理器映射器

不同的处理器映射器对URL处理的方式也不相同,使用对应的处理器映射器之后,我们的前端请求规则也需要发生响应的变化

SpringMVC提供的处理器映射器:

1:BeanNameUrlHandlerMappering:根据控制器的Id访问控制器

2:SimpleUrlHandlerMapping 根据控制器配置的URL访问(默认)

配置处理器映射器:

  • 在SpringMVC的配置文件中通过Bean标签声明处理器映射器
  • 配置 BeanNameUrlHandlerMapping
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

例子:

 <bean id="bookController" class="com.qfdue.controller.BookController"></bean>
@Controller
//@RequestMapping("/book")    
//默认时bookController   
//<bean id="bookController"class="com.qfdue.controller.BookController"></bean>

public class BookController {

}
  • 配置SimpleUrlHandlerMapping
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
        <!--这里也可以通过注解的方式在controller上进行配置@RequestMapping("/aaa")-->
            <prop key="/aaa">bookController</prop>
            <prop key="/bbb">studentController</prop>
        </props>
    </property>
</bean>

4.4 视图解析器

SpringMVC提供了多个视图解析器:

1:UrlBasedViewResolver

2:InternalResourceViewResolver

  • UrlBasedViewResolver 需要依赖 jstl 包

  • 添加JSTL的依赖

pom.xml

<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
  • 配置视图解析器

spring-servlet.xml

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
</bean>
  • InternalResourceViewResolver(不需要添加jstl依赖)
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
</bean>

五: 日期格式处理

5.1 在控制器中使用对象接收数据

  • 前端 前端与后端的 属性和name(key)要相等
<form action="test/add" method="post">
    <p>图书名称:<input type="text" name="bookId"></p>
    <p>图书作者:<input type="text" name="bookName"></p>
    <p>图书价格:<input type="text" name="bookPrice"></p>
    <p>图书出版时间:<input type="text" name="publish"></p>
    <p><input type="submit" value="提交"></p>
</form>
  • 后端
package com.liguoqing.beans;

import java.util.Date;

public class Book {
    private int bookId;
    private String bookName;
    private String bookAuthor;
    private double bookPrice;
    private Date publish;

    public Book(int bookId, String bookName, String bookAuthor, double bookPrice) {
        this.bookId = bookId;
        this.bookName = bookName;
        this.bookAuthor = bookAuthor;
        this.bookPrice = bookPrice;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bookId=" + bookId +
                ", bookName='" + bookName + '\'' +
                ", bookAuthor='" + bookAuthor + '\'' +
                ", bookPrice=" + bookPrice +
                ", publish=" + publish +
                '}';
    }

    public int getBookId() {
        return bookId;
    }

    public void setBookId(int bookId) {
        this.bookId = bookId;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getBookAuthor() {
        return bookAuthor;
    }

    public void setBookAuthor(String bookAuthor) {
        this.bookAuthor = bookAuthor;
    }

    public double getBookPrice() {
        return bookPrice;
    }

    public void setBookPrice(double bookPrice) {
        this.bookPrice = bookPrice;
    }

    public Date getPublish() {
        return publish;
    }

    public void setPublish(Date publish) {
        this.publish = publish;
    }

    public Book(int bookId, String bookName, String bookAuthor, double bookPrice, Date publish) {
        this.bookId = bookId;
        this.bookName = bookName;
        this.bookAuthor = bookAuthor;
        this.bookPrice = bookPrice;
        this.publish = publish;
    }

    public Book() {
    }
}
--------------------------
package com.liguoqing.controllers;

import com.liguoqing.beans.Book;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Date;

@Controller
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/add")
    //表单提交的多个参数,在控制器方法中可以使用对象接收,
    //但是提交的数据的key必须要与对象的属性一致
    public String addBook(Book book){
        System.out.println(book);
        return "tips";
    }

}


spring-servlet.xml:
-------


<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
</bean>

5.2 日期格式处理

如果前端需要输入日期数据,在控制器中转换成Date对象,SpringMVC要求前端输入的日期格式必须为yyyy/MM/DD

如果甲方要求日期格式必须为指定的格式,而这个指定格式SpringMVC不接受,该如何处理呢?

自定义日期转换器:

5.2.1 创建自定义日期转换器

package com.liguoqing.utils;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
* 1:创建一个类实现Converter接口,泛型指定从什么类型转换为什么类型
* 2:实现Converter准换方法
* */
public class MyDateConverter implements Converter<String,Date> {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");

    public Date convert(String s) {
        Date date = null;
        try {
            date = sdf.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

5.2.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:aop="http://www.springframework.org/schema/aop"
        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
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc.xsd">


    <!--    声明使用注解配置-->
    <context:annotation-config/>
    <!--    声明Spring工厂注解的扫描范围-->
    <context:component-scan base-package="com.liguoqing"/>
    --------------------------------------------------------------------------------
    <!--    声明mvc使用注解驱动-->
    <mvc:annotation-driven conversion-service="converterFactory"/>
------------------------------------------------------------------------

<!--放行资源-->
    <mvc:resources mapping="/css/**" location="/css/"/>
    <mvc:resources mapping="/pages/**" location="/pages/"/>
    <mvc:resources mapping="/imgs/**" location="/imgs/"/>
    <mvc:resources mapping="/js/**" location="/js/"/>

<!--HandlerMapping-->
<!--    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>-->

<!--    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">-->
<!--        <property name="mappings">-->
<!--            <props>-->
<!--                <prop key="/aaa">bookController</prop>-->
<!--                <prop key="/bbb">studentController</prop>-->
<!--            </props>-->
<!--        </property>-->
<!--    </bean>-->


<!--    <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">-->
<!--        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>-->
<!--        <property name="prefix" value="/"/>-->
<!--        <property name="suffix" value=".jsp"/>-->
<!--    </bean>-->

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

-----------------------------------------------------------
<!--自定义日期转换器-->
    <bean id="converterFactory" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
<!--                //这里可以配置多个-->
                <bean class="com.liguoqing.utils.MyDateConverter"/>
            </set>
        </property>
    </bean>
----------------------------------------------

</beans>





//自己定义一个转换类
//MyDateConverter.class
package com.liguoqing.utils;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
* 1:创建一个类实现Converter接口,泛型指定从什么类型转换为什么类型
* 2:实现Converter准换方法
* */
public class MyDateConverter implements Converter<String,Date> {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");

    public Date convert(String s) {
        Date date = null;
        try {
            date = sdf.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

六:文件上传

6.1 SpringMVC框架部署

  • 基于Maven创建web工程

  • 添加SpringMVC所需的依赖

    • Spring-context aspects jdbc test web webmvc jackson
  • 创建SpringMVC配置文件

  • 在web.xml中配置SpringMVC的前端控制器

  • 在web.xml中配置SpringMVC的编码过滤器

  • 配置静态资源处理策略

springmvc-demo3.zip

6.2 文件上传

案例:添加图书,同时提交图书的封面图片

6.2.1 前端提交文件

  • 表单提交方式必须为post
  • 表单 enctype属性 设置为 multipart/form-data
<form action="book/add" method="post" enctype="multipart/form-data">
    <p>图书名称:<input type="text" name="bookName"></p>
    <p>图书作者:<input type="text" name="bookAuthor"></p>
    <p>图书价格:<input type="text" name="bookPrice"></p>
    <p>图书封面:<input type="file" name="ImgFile"></p>
    <p>提交:<input type="submit" name="提交"></p>
</form>

6.2.2 控制器接收数据和文件

SpringMVC处理上传文件需要借助CommonsMultipartResolver文件解析器

img

  • 添加依赖:commons-io commons-fileupload
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
  • 在spring-servlet.xml中配置文件解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--一些属性,自己百度-->
    <property name="maxUploadSize" value="10240000"/>
    <property name="maxInMemorySize" value="10240"/>
    <property name="defaultEncoding" value="utf-8"/>
</bean>
  • 控制器接收文件

  • 在处理文件上传的方法中定义一个 MultipartFile 类型的对象,就可以接收图片了

package com.liguoqing.controller;

import com.liguoqing.beans.Book;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

@Controller
@RequestMapping("/book")
public class BookController {

    @RequestMapping("/add")
    public String addBook(Book book, MultipartFile ImgFile, HttpServletRequest request) throws IOException {
        System.out.println("~~~~addBook");
        System.out.println(book);
        System.out.println(ImgFile);
        //ImgFile表示上传的图片
        //1:截取上传文件的后缀名,生成新的文件名
        String originalFilename = ImgFile.getOriginalFilename();
        String ext = originalFilename.substring( originalFilename.lastIndexOf(".") );// .jpg
        String filename = System.currentTimeMillis()+ext;

        //2:获取imgs目录在服务器的路径
        String dir = request.getServletContext().getRealPath("imgs");
        String savePath = dir + "/" + filename;//存储路径(C:/asd/ad/asdf/img.jpg)

        //3:保存文件
        ImgFile.transferTo(new File(savePath));

        //4:将图片的访问路径设置到对象
        book.setBookImg("imgs/"+ filename);

        //5:调用service保存book到数据库

        return "/tips.jsp";
    }

}

6.3 文件下载

6.3.1

img

@RequestMapping("/list")
@ResponseBody
public String[] listImgs(HttpServletRequest request){
    //1:从imgs目录下获取所有的图片信息
    String dir = request.getServletContext().getRealPath("imgs");
    File imgDir = new File(dir);
    String[] filenames = imgDir.list();
    return filenames;
}

6.3.2 实现文件下载

img

七:同一异常处理

在我们的应用系统运行的过程中,可能由于运行环境,用户操作,资源不足等各方面的原因导致系统出现异常(HTTP状态异常、Java异常Exception);如果系统出现了异常,这些异常将会通过浏览器呈现给用户,而这种异常的显示是没有必要的,因此我们可以在服务器进行特定的处理——当系统出现异常之后,呈现给用户一个统一的,可读的提示页面。

7.1 HTTP异常状态统一处理

HTTP Status 404

  • 创建一个用于异常提示的页面:404.jsp
  • 在web.xml中进行配置
<error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
</error-page>

7.2 Java代码异常的统一处理(其他异常)

7.2.1基于Servlet-api的处理

  • 创建异常提示页面:err.jsp
  • 在web.xml中进行配置
<error-page>
    <exception-type>java.lang.NullPointerException</exception-type>
    <location>/err.jsp</location>
</error-page>
  • 使用异常处理类进行统一处理

img

八:拦截器

8.1 拦截器介绍

SpringMVC提供的拦截器就类似与Servlet-api中的过滤器,可以对控制器的请求进行拦截实现相关的预处理和后处理。

image-20220426093604255

  • 过滤器(web.xml知道你的存在,tomcat管理)

    是Servlet规范的一部分,所有web项目都可以使用

    过滤器在web.xml配置(可以使用注解),

    能够拦截所有web请求

  • 拦截器(dispatchservlet知道拦截器的存在,springMvc管理)

    是SpringMVC框架的实现,只有在SpringMVC框架中才能使用

    拦截器在SpringMVC配置文件进行配置,

    不会拦截SpringMVC放行的资源(js/html/css…)

      ------------------------------------------------ <!--放行资源-->
        <mvc:resources mapping="/css/" location="/css/"/>
        <mvc:resources mapping="/pages/" location="/pages/"/>
        <mvc:resources mapping="/imgs/" location="/imgs/"/>
        <mvc:resources mapping="/js/" location="/js/"/>
    

8.2 自定义拦截器

img

8.2.1 创建拦截器

实现HandInteceptor接口 满足拥BookId key值才能被拦截器预处理

img

8.2.2 配置拦截器

img

8.3拦截器链

将多个拦截器按照一定的顺序构成一个拦截器链

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="com.qfdue.utils.MyInterceptor1"/>
            <mvc:exclude-mapping path="/book/query"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="com.qfdue.utils.MyInterceptor2"/>
            <mvc:exclude-mapping path="/book/query"/>
        </mvc:interceptor>
    </mvc:interceptors>

img

如何将有道云笔记搬运到本地

image-20220421234754361

2.可能是格式刷

[外链图片转存中…(img-roIyE5zD-1651847342877)]

八:拦截器

8.1 拦截器介绍

SpringMVC提供的拦截器就类似与Servlet-api中的过滤器,可以对控制器的请求进行拦截实现相关的预处理和后处理。

[外链图片转存中…(img-XVDVy1wL-1651847342878)]

  • 过滤器(web.xml知道你的存在,tomcat管理)

    是Servlet规范的一部分,所有web项目都可以使用

    过滤器在web.xml配置(可以使用注解),

    能够拦截所有web请求

  • 拦截器(dispatchservlet知道拦截器的存在,springMvc管理)

    是SpringMVC框架的实现,只有在SpringMVC框架中才能使用

    拦截器在SpringMVC配置文件进行配置,

    不会拦截SpringMVC放行的资源(js/html/css…)

      ------------------------------------------------ <!--放行资源-->
        <mvc:resources mapping="/css/" location="/css/"/>
        <mvc:resources mapping="/pages/" location="/pages/"/>
        <mvc:resources mapping="/imgs/" location="/imgs/"/>
        <mvc:resources mapping="/js/" location="/js/"/>
    

8.2 自定义拦截器

[外链图片转存中…(img-47RvTUjn-1651847342880)]

8.2.1 创建拦截器

实现HandInteceptor接口 满足拥BookId key值才能被拦截器预处理

[外链图片转存中…(img-iIkNSwWC-1651847342881)]

8.2.2 配置拦截器

[外链图片转存中…(img-SgN5mGON-1651847342881)]

8.3拦截器链

将多个拦截器按照一定的顺序构成一个拦截器链

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="com.qfdue.utils.MyInterceptor1"/>
            <mvc:exclude-mapping path="/book/query"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="com.qfdue.utils.MyInterceptor2"/>
            <mvc:exclude-mapping path="/book/query"/>
        </mvc:interceptor>
    </mvc:interceptors>

[外链图片转存中…(img-Vor4LotI-1651847342882)]

如何将有道云笔记搬运到本地

[外链图片转存中…(img-Bw5bPlgp-1651847342890)]

2.可能是格式刷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值