Java 之 SpringMVC(一篇文章精通系列)

x33g5p2x  于2021-09-19 转载在 Java  
字(28.9k)|赞(0)|评价(0)|浏览(331)

一、SpringMVC

1、SpringMVC概述

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架

属于SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。

SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,

全面超越 Struts2,成为最优秀的 MVC 框架。

它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,

而无须实现任何接口。

同时它还支持 RESTful 编程风格的请求。

2、SpringMVC快速入门(实战)

需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。

开发步骤:

  • 导入SpringMVC相关坐标
  • 配置SpringMVC核心控制器DispathcerServlet
  • 创建Controller类和视图页面
  • 使用注解配置Controller类中业务方法的映射地址
  • 配置SpringMVC核心文件 spring-mvc.xml
  • 客户端发起请求测试
(1)创建SpringMVC工程

  • 删除web.xml和pom.xml当中的一些内容

  • 删除webapp下的WEB-INF当中的applicationContext.xml和log4j.xml,

  • 没有的文件创建出来

(2)导入Spring和SpringMVC的坐标

<?xml version="1.0" encoding="UTF-8"?>

<!-- $Id: pom.xml 642118 2008-03-28 08:04:16Z reinhard $ -->
<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/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>

  <name>itbluebox-springmvc</name>
  <groupId>cn.itbluebox</groupId>
  <artifactId>itbluebox-springmvc</artifactId>
  <version>1.0.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.32</version>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.10</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.2.1</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

</project>
(3)创建Controller和业务方法

package cn.itbluebox.controller;

public class QuickController {

    public String quickMethod(){

        System.out.println("quickMethod running.....");

        return "index.jsp";
    }

}
(4)创建视图页面index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>Hello SpringMVC!</h2>
</body>
</html>
(5)配置注解

package cn.itbluebox.controller;

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

@Controller
public class QuickController {

    @RequestMapping("/quick")
    public String quickMethod(){

        System.out.println("quickMethod running.....");

        return "index.jsp";
    }

}
(6)创建spring-mvc.xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--配置注解扫描-->
    <context:component-scan base-package="cn.itbluebox"/>

</beans>
(7)在web.xml配置SpringMVC的核心控制器

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
(8)引入Tomcat插件

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8090</port>
          <path>/</path>
        </configuration>
      </plugin>

    </plugins>

  </build>

运行测试

http://localhost:8090/quick

(9)配置视图解析器

视图解释器,不设置后缀直接跳转

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

package cn.itbluebox.controller;

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

@Controller
public class QuickController {

    @RequestMapping("/quick")
    public String quickMethod(){
        System.out.println("quickMethod running.....");
        return "index";
    }

}

运行

http://localhost:8090/quick

3、SpringMVC流程图示

4、知识要点

SpringMVC的开发步骤

  • 导入SpringMVC相关坐标
  • 配置SpringMVC核心控制器DispathcerServlet
  • 创建Controller类和视图页面
  • 使用注解配置Controller类中业务方法的映射地址
  • 配置SpringMVC核心文件 spring-mvc.xml
  • 客户端发起请求测试

二、SpringMVC 组件解析

1、SpringMVC的执行流程

  • 用户发送请求至前端控制器DispatcherServlet。
  • DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  • 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
  • DispatcherServlet调用HandlerAdapter处理器适配器。
  • HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
  • Controller执行完成返回ModelAndView。
  • HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
  • DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
  • ViewReslover解析后返回具体View。
  • DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
  • DispatcherServlet响应用户。

2、SpringMVC组件解析

前端控制器:DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,
DispatcherServlet 是整个流程控制的中心,由
它调用其它组件处理用户的请求,
DispatcherServlet 的存在降低了组件之间的耦合性。
1.
处理器映射器:HandlerMapping
HandlerMapping 负责根据用户请求找到 Handler 即处理器,
SpringMVC 提供了不同的映射器实现不同的
映射方式,例如:配置文件方式,实现接口方式,注解方式等。
1.
处理器适配器:HandlerAdapter
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,
通过扩展适配器可以对更多类型的处理器进行执行。
1.
处理器:Handler
它就是我们开发中要编写的具体业务控制器。
由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
1.
视图解析器:View Resolver
View Resolver 负责将处理结果生成 View 视图,
View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,
最后对 View 进行渲染将处理结果通过页面展示给用户。
1.
视图:View
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。
一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,
需要由程序员根据业务需求开发具体的页面

3、SpringMVC注解解析

@RequestMapping

作用:用于建立请求 URL 和处理请求方法之间的对应关系

位置:类上,请求URL 的第一级访问目录。

此处不写的话,就相当于应用的根目录
方法上,请求 URL 的第二级访问目录,
与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径

属性

value:用于指定请求的URL。它和path属性的作用是一样的
method:用于指定请求的方式
params:用于指定限制请求参数的条件。它支持简单的表达式。

要求请求参数的key和value必须和配置的一模一样

例如
params = {"accountName"},表示请求参数必须有accountName
params = {"moeny!100"},表示请求参数中money不能是100

(1)mvc命名空间引入

命名空间:

xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"

约束地址:

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc.xsd
(2)组件扫描

SpringMVC基于Spring容器,所以在进行SpringMVC操作时,

需要将Controller存储到Spring容器中,

如果使用@Controller注解标注的话,就需要使用

<context:component-scan base-package=“cn.itbluebox.controller"/>

进行组件扫描。

4、SpringMVC的XML配置解析

  1. 视图解析器
    SpringMVC有默认组件配置,默认组件都是DispatcherServlet.properties配置文件中配置的,该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties,该文件中配置了默认的视图解析器,如下:
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

翻看该解析器源码,可以看到该解析器的默认设置,如下:

REDIRECT_URL_PREFIX = "redirect:"  --重定向前缀
FORWARD_URL_PREFIX = "forward:"    --转发前缀(默认值)
prefix = "";     --视图名称前缀
suffix = "";     --视图名称后缀
<!--配置内部资源视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"></property>
    <property name="suffix" value=".jsp"></property>
 </bean>

5、知识要点

SpringMVC的相关组件

  • 前端控制器:DispatcherServlet
  • 处理器映射器:HandlerMapping
  • 处理器适配器:HandlerAdapter
  • 处理器:Handler
  • 视图解析器:View Resolver
  • 视图:View

SpringMVC的注解和配置
请求映射注解:@RequestMapping
视图解析器配置:

REDIRECT_URL_PREFIX = "redirect:"  
FORWARD_URL_PREFIX = "forward:"    
prefix = "";     
suffix = "";

三、SpringMVC的数据响应

1、SpringMVC的数据响应方式

1) 页面跳转
直接返回字符串
通过ModelAndView对象返回

2) 回写数据
直接返回字符串
返回对象或集合

2、页面跳转

Forward(请求转发)
Redirect(重定向)

(1)返回字符串形式

直接返回字符串:

此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转。

返回带有前缀的字符串:

转发:
forward:/WEB-INF/views/index.jsp

重定向:
redirect:/index.jsp
(2)创建JSP页面

<%--
  Created by IntelliJ IDEA.
  User: ZHENG
  Date: 2021/9/14
  Time: 14:27
  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>
<h1>views下的index.jsp</h1>
${name}
</body>
</html>

完善webapp下的index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>Hello SpringMVC!</h2>

    ${name}
</body>
</html>
(3)返回ModelAndView对象(在刚刚的QuickController当中写如下接口接口)

Redirect(重定向)

@RequestMapping("/quick002")
    public ModelAndView quickMethod2() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("redirect:index.jsp");
        return modelAndView;
    }

http://localhost:8090/quick002

Forward(请求转发)

@RequestMapping("/quick003")
    public ModelAndView quickMethod3() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("forward:/WEB-INF/views/index.jsp");
        return modelAndView;
    }

http://localhost:8090/quick003

(4)向request域存储数据(在刚刚的QuickController当中写如下接口接口)

在进行转发时,往往要向request域中存储数据,

在jsp页面中显示,那么Controller中怎样向request域中存储数据呢?

  • 通过SpringMVC框架注入的request对象setAttribute()方法设置
@RequestMapping("/quick004")
    public String quickMethod4(HttpServletRequest request) {
        request.setAttribute("name", "zhangsan");
        return "index";
    }

http://localhost:8090/quick004

  • 通过ModelAndView的addObject()方法设置
@RequestMapping("/quick005")
    public ModelAndView quickMethod5() {

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("forward:/WEB-INF/views/index.jsp");
        modelAndView.addObject("name", "list");
        return modelAndView;

    }

http://localhost:8090/quick005

3、回写数据

(1)直接返回字符串

Web基础阶段,客户端访问服务器端,
如果想直接回写字符串作为响应体返回的话,只需要使用

response.getWriter().print(“hello world”) 即可,

那么在Controller中想直接回写字符串该怎样呢?

  • 通过SpringMVC框架注入的response对象,
    使用response.getWriter().print(“hello world”) 回写数据,
    此时不需要视图跳转,业务方法返回值为void。
@RequestMapping("/quick006")
    public void quickMethod6(HttpServletResponse response)
            throws IOException {
        response.getWriter().print("hello world");
    }

http://localhost:8090/quick006

  • 将需要回写的字符串直接返回,但此时需要通过
    @ResponseBody注解告知SpringMVC框架,
    方法返回的字符串不是跳转是直接在http响应体中返回。
@RequestMapping("/quick007")
    @ResponseBody
    public String quickMethod7() throws IOException{
        return "hello springMVC!!!";
    }

http://localhost:8090/quick007

  • 在异步项目中,客户端与服务器端往往要进行json格式字符串交互,
    此时我们可以手动拼接json字符串返回。
@RequestMapping("/quick008")
    @ResponseBody
    public String quickMethod8() throws IOException {
        return "{\"name\":\"zhangsan\",\"age\":18}";
    }

http://localhost:8090/quick008

(2)返回字符串(JSON)格式
  • 引入依赖

上述方式手动拼接json格式字符串的方式很麻烦,

开发中往往要将复杂的java对象转换成json格式的字符串,

我们可以使用web阶段学习过的json转换工具jackson进行转换,导入jackson坐标。

<!--jackson-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>
  • 创建User对象

package cn.itbluebox.pojo;

public class User {

    private String name;
    private Integer age;

    public User() {
    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • QuickController当中创建quickMethod9方法

@RequestMapping("/quick009")
    @ResponseBody
    public String quickMethod9() throws IOException{
        User user = new User();
        user.setName("zhangsan");
        user.setAge(18);
        ObjectMapper objectMapper = new ObjectMapper();
        String s = objectMapper.writeValueAsString(user);
        return s;
    }

http://localhost:8090/quick009

(3)返回对象或集合

通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,

为处理器适配器配置消息转换参数,指定使用jackson进行对象或集合的转换,

因此需要在

spring-mvc.xml中进行如下配置:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                </bean>
            </list>
        </property>
    </bean>
  • 返回User对象

@RequestMapping("/quick010")
    @ResponseBody
    public User quickMethod10() throws IOException{
        User user = new User();
        user.setName("lisi");
        user.setAge(19);
        return user;
    }

  • 返回User对象的集合

@RequestMapping("/quick011")
    @ResponseBody
    public ArrayList<User> quickMethod11() throws IOException{
        ArrayList<User> users = new ArrayList<User>();
        User user1 = new User("zhangsan",19);
        User user2 = new User("lisi",29);
        User user3 = new User("wangyu",39);
        User user4 = new User("zhaoliu",29);
        User user5 = new User("zhangzhan",39);
        users.add(user1);
        users.add(user2);
        users.add(user3);
        users.add(user4);
        users.add(user5);
        return users;
    }

(4)返回对象或者集合(简化配置)

在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多,因此,我们可以使用mvc的注解驱动代替上述配置。

<!--mvc的注解驱动-->
<mvc:annotation-driven/>

在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、

视图解析器称为 SpringMVC 的三大组件。

使用<mvc:annotation-driven>

自动加载 RequestMappingHandlerMapping(处理映射器)


RequestMappingHandlerAdapter( 处 理 适 配 器 ),

可用在Spring-xml.xml配置文件中使用

<mvc:annotation-driven>替代注解处理器和适配器的配置。

同时使用<mvc:annotation-driven>默认底层就会集成jackson进行对象或集合的json格式字符串的转换。

http://localhost:8090/quick011

(5)SpringMVC的数据响应方式

1) 页面跳转
直接返回字符串
通过ModelAndView对象返回

2) 回写数据
直接返回字符串
返回对象或集合

四、SpringMVC 获得请求数据

1、获得请求参数

客户端请求参数的格式是:name=value&name=value… …

服务器端要获得请求的参数,有时还需要进行数据的封装,
SpringMVC可以接收如下类型的

参数:

  • 基本类型参数
  • POJO类型参数
  • 数组类型参数
  • 集合类型参数

Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。

@RequestMapping("/quick012")
    @ResponseBody
    public void quickMethod12(String name,int age) throws IOException{
        System.out.println(name);
        System.out.println(age);

    }

http://localhost:8090/quick012?name=lisi&age=19

2、获得POJO类型参数

Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。

@RequestMapping("/quick013")
    @ResponseBody
    public void quickMethod13(User user) throws IOException{
        System.out.println(user);
    }

http://localhost:8090/quick013?name=lisi&age=19

3、获得数组类型参数

Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。

@RequestMapping("/quick014")
    @ResponseBody
    public void quickMethod14(String[] strs) throws IOException{
        System.out.println(Arrays.asList(strs));
    }

http://localhost:8090/quick014?strs=111&strs=222&strs=333

4、获得集合类型参数

获得集合参数时,要将集合参数包装到一个POJO中才可以。

(1)创建Vo对象

package cn.itbluebox.pojo;

import java.util.ArrayList;

public class Vo {

    private ArrayList<User> userList;

    public Vo() {
    }

    public Vo(ArrayList<User> userList) {
        this.userList = userList;
    }

    public ArrayList<User> getUserList() {
        return userList;
    }

    public void setUserList(ArrayList<User> userList) {
        this.userList = userList;
    }

    @Override
    public String toString() {
        return "Vo{" +
                "userList=" + userList +
                '}';
    }
}
(2)在QuickController当中创建quickMethod15方法

@RequestMapping("/quick015")
    @ResponseBody
    public void quickMethod15(Vo vo) throws IOException{
        System.out.println(vo.getUserList());
    }
(3)创建login.jsp

<%--
  Created by IntelliJ IDEA.
  User: ZHENG
  Date: 2021/9/14
  Time: 15:36
  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>

    <form action="${pageContext.request.contextPath}/quick015" method="post">

        name:<input type="text" name="userList[0].name" ><br>
        age:<input type="text" name="userList[0].age" ><br>
        name:<input type="text" name="userList[1].name" ><br>
        age:<input type="text" name="userList[1].age" ><br>
        name:<input type="text" name="userList[3].name" ><br>
        age:<input type="text" name="userList[3].age" ><br>

        <input type="submit" value="提交"><br>

    </form>

</body>
</html>

5、获得集合类型参数(Ajax提交)

当使用ajax提交时,可以指定contentType为json形式,

那么在方法参数位置使用

@RequestBody

可以直接接收集合数据而无需使用POJO进行包装。

(1)引入jquery-3.3.1.js,并创建login.html

创建ajax.html页面

<html>
<head>
    <title>Title</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="js/jquery-3.3.1.js"></script>
    <script> var userList = new Array(); userList.push({name:"zhangsan",age:18}); userList.push({name:"lisi",age:28}); $.ajax({ type:"POST", url:"/quick016", data:JSON.stringify(userList), contentType:"application/json;charset=utf-8" }); </script>
</head>
<body>

</body>
</html>
(2)修改web.xml

因为默认的配置DispatcherServlet屏蔽了html页面的访问,你需要加上如下:

<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
(3)修改spring-mvc.xml

注意:通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种方式指定放行静态资源:

  • spring-mvc.xml配置文件中指定放行的资源
<!--开放资源的访问-->
   <!-- <mvc:resources mapping="/js/**" location="/js/"/>-->
    <mvc:default-servlet-handler/>
  • 使用<mvc:default-servlet-handler/>标签

(4)在QuickController创建quickMethod16方法

当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用

@RequestBody可以直接接收集合数据而无需使用POJO进行包装。

@RequestMapping("/quick016")
    @ResponseBody
    public void quickMethod16(@RequestBody List<User> userList) throws IOException{
        System.out.println(userList);
    }
(5)运行测试

(6)请求数据乱码问题

修改ajax.html

刷新页面

当post请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码的过滤。修改web.xml

<filter>
        <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  • 从新运行

http://localhost:8090/ajax.html

刷新页面

6、参数绑定

(1)参数绑定注解@requestParam
1)当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过

@RequestParam注解显示的绑定。

  • 创建login2.jsp

<%--
  Created by IntelliJ IDEA.
  User: ZHENG
  Date: 2021/9/14
  Time: 16:55
  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>
    <form action="${pageContext.request.contextPath}/quick017" method="post" >
        <input type="text" name="name" ><br>
        <input type="submit" value="提交" ><br>
    </form>
</body>
</html>
  • 在QuickController当中创建quickMethod17方法

@RequestMapping("/quick017")
    @ResponseBody
    public void quickMethod17(@RequestParam("name") String username) throws IOException{
        System.out.println(username);
    }
  • 运行测试

http://localhost:8090/login2.jsp

2)当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定。
<form action="${pageContext.request.contextPath}/quick14" method="post">
    <input type="text" name="name"><br>
    <input type="submit" value="提交"><br>
</form>
@RequestMapping("/quick14")
@ResponseBody
public void quickMethod14(@RequestParam("name") String username) 
throws IOException {
	System.out.println(username);
}
3)注解@RequestParam还有如下参数可以使用:
  • value:与请求参数名称
  • required:此在指定的请求参数是否必须包括,默认是true,提交时如果没有此参数则报错
  • defaultValue:当没有指定请求参数时,则使用指定的默认值赋值

@RequestMapping("/quick018")
    @ResponseBody
    public void quickMethod18(
            @RequestParam(
                    value = "name",
                    required = false,
                    defaultValue = "itbluebox")
                    String username) 
            throws IOException{
        System.out.println(username);
    }
  • 修改login2.jsp

<%--
  Created by IntelliJ IDEA.
  User: ZHENG
  Date: 2021/9/14
  Time: 16:55
  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>

    <form action="${pageContext.request.contextPath}/quick018" method="post" >
        <input type="text" name="name" ><br>
        <input type="submit" value="提交" ><br>
    </form>

</body>
</html>
  • 从新运行并测试

http://localhost:8090/login2.jsp

显示默认值

(8)获得Restful风格的参数

Restful是一种软件架构风格、设计风格,而不是标准,
只是提供了一组设计原则和约束条件。
主要用于客户端和服务器交互类的软件,
基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。

Restful风格的请求是使用“url+请求方式”表示一次请求目的的,

HTTP 协议里面四个表示操作方式的动词如下:

  • GET:用于获取资源
  • POST:用于新建资源
  • PUT:用于更新资源
  • DELETE:用于删除资源

例如:

  • /user/1 GET : 得到 id = 1 的 user
  • /user/1 DELETE: 删除 id = 1 的 user
  • /user/1 PUT: 更新 id = 1 的 user
  • /user POST: 新增 user

上述url地址/user/1中的1就是要获得的请求参数,
在SpringMVC中可以使用占位符进行参数绑定。

地址/user/1可以写成/user/{id},占位符{id}对应的就是1的值。

在业务方法中我们可以使用

@PathVariable注解进行占位符的匹配获取工作。

@RequestMapping("/quick019/{name}")
    @ResponseBody
    public void quickMethod19(@PathVariable(value = "name",required = true) String name){
        System.out.println(name);
    }

直接在浏览器输入如下地址:

http://localhost:8090/quick019/zhangsan

(9)自定义类型转换器

SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。

但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,

例如:日期类型的数据就需要自定义转换器。

自定义类型转换器的开发步骤:

  • 定义转换器类实现Converter接口
  • 在配置文件中声明转换器
  • <annotation-driven>中引用转换器
1)定义转换器类实现Converter接口

package cn.itbluebox.converter;
import org.springframework.core.convert.converter.Converter;

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

public class DateConverter implements Converter<String, Date> {

    public Date convert(String source) {
        //将日期字符串转换成日期对象 返回
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date data = null;
        try {
            data = format.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return data;
    }
}
2)在配置文件中声明转换器

spring-mvc.xml

<bean id="converterService" class="org.springframework.context.support.ConversionServiceFactoryBean">

        <property name="converters">
            <list>
                <bean class="cn.itbluebox.converter.DateConverter"></bean>
            </list>
        </property>

    </bean>

<annotation-driven>中引用转换器

<!--mvc的注解驱动-->
    <mvc:annotation-driven conversion-service="converterService"/>
(10)获得Servlet相关API

SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下:

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession

@RequestMapping("/quick020")
    @ResponseBody
    public void quickMethod20(HttpServletRequest request,
                              HttpServletResponse response,
                              HttpSession session){

        System.out.println(request);
        System.out.println(response);
        System.out.println(session);

    }

运行测试

http://localhost:8090/quick020

(11)获得请求头
1) @RequestHeader

使用
@RequestHeader可以获得请求头信息,
相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:
value:请求头的名称
required:是否必须携带此请求头

@RequestMapping("/quick021")
    @ResponseBody
    public void quickMethod21(
            @RequestHeader(
                    value = "User-Agent",
                    required = false)
                    String headerValue
    ){

        System.out.println(headerValue);

    }
2)@CookieValue

使用@CookieValue可以获得指定Cookie的值

@CookieValue注解的属性如下:

value:指定cookie的名称
required:是否必须携带此cookie

@RequestMapping("/quick022")
    @ResponseBody
    public void quickMethod22(
            @CookieValue(
                    value = "JSESSIONID",
                    required = false) String jsessionid){

        System.out.println(jsessionid);

    }

http://localhost:8090/quick022

五、文件上传

1、件上传客户端三要素

表单项type=“file”
表单的提交方式是post
表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”

(2)创建upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/quick023" method="post" enctype="multipart/form-data">

        名称:<input type="text" name="name"><br>
        文件:<input type="file" name="file"><br>
        <input type="submit" value="提交">

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

2、文件上传原理

当form表单修改为多部分表单时,request.getParameter()将失效。
enctype=“application/x-www-form-urlencoded”时,form表单的正文内容格式是:key=value&key=value&key=value
当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式:

3、单文件上传步骤

  • 导入fileupload和io坐标
  • 配置文件上传解析器
  • 编写文件上传代码
1)导入fileupload和io坐标

<dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
2)配置文件上传解析器(spring-mvc.xml)

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--上传文件总大小-->
        <property name="maxUploadSize" value="5242800"/>
        <!--上传单个文件的大小-->
        <property name="maxUploadSizePerFile" value="5242800"/>
        <!--上传文件的编码类型-->
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>
3)编写文件上传代码

在c盘下创建upload空文件夹

完善QuickController当中的quickMethod23

@RequestMapping("/quick023")
    @ResponseBody
    public void quickMethod23(String name, MultipartFile file)throws IOException{
        //获得文件名称
        String file= uploadFile.getOriginalFilename();
        //保存文件
        file.transferTo(new File("C:\\upload\\"+originalFilename));
    }
4)运行测试

http://localhost:8090/upload.jsp

上传成功

4、多文件上传实现

多文件上传,只需要将页面修改为多个文件上传项,
将方法参数MultipartFile类型修改为MultipartFile[]即可

(1)修改upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/quick024" method="post" enctype="multipart/form-data">

        名称:<input type="text" name="name"><br>
        文件1:<input type="file" name="files"><br>
        文件2:<input type="file" name="files"><br>
        文件3:<input type="file" name="files"><br>
        文件4:<input type="file" name="files"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>
(2)QuickController创建quickMethod24方法

@RequestMapping("/quick024")
    @ResponseBody
    public void quickMethod24(String name, MultipartFile[] files)throws IOException{
        //获得文件名称
        for(MultipartFile file : files){
            String originalFilename = file.getOriginalFilename();
            //保存文件
            file.transferTo(new File("C:\\upload\\"+originalFilename));
        }
    }
(3)运行测试

http://localhost:8090/upload.jsp

(4)知识要点

MVC实现数据请求方式
基本类型参数
POJO类型参数
数组类型参数
集合类型参数
*
MVC获取数据细节
中文乱码问题
@RequestParam 和 @PathVariable
自定义类型转换器
获得Servlet相关API
@RequestHeader 和 @CookieValue
文件上传

相关文章

微信公众号

最新文章

更多

目录