SpringMVC

本文详细介绍了SpringMVC的各个核心概念和使用方法,包括MVC架构模式、SpringMVC简介、基本使用、注解开发、请求参数处理、请求类型指定、响应处理、文件上传下载、静态资源映射、异常处理、拦截器、Restful支持、JSON数据处理、跨域问题及常用注解。还涵盖了SSM框架整合和通过Maven搭建SSM项目,深入讲解了用户登录业务的实现以及日志记录。
摘要由CSDN通过智能技术生成

SpringMVC 实战*

主要内容
MVC 架构模式简介
SpringMVC 简介
SpringMVC 的基本使用
SpringMVC 基于注解开发
获取请求参数
指定处理请求类型
SpringMVC 处理响应
文件上传与下载
静态资源映射
SpringMVC 的异常处理
SpringMVC 拦截器
SpringMVC 对 Restful 风格的支持
JSON 数据处理
SpringMVC 解决跨域请求问题
SpringMVC 常用注解
SSM 框架整合
基于 Maven 搭建 SSM 整合

学习目标

在这里插入图片描述

一、 MVC 架构模式简介

MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责。
 模型:用于存储数据以及处理用户请求的业务逻辑。
 视图:向控制器提交数据,显示模型中的数据。
 控制器:根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有关结果交给哪个视图更新显示。
基于 Servlet 的 MVC 模式
 模型:一个或多个 JavaBean 对象,用于存储数据(实体模型,由 JavaBean 类创建)和处理业务逻辑(业务模型,由一般的 Java 类创建)。
 视图:一个或多个 JSP 页面,向控制器提交数据和为模型提供数据显示,JSP 页面主要使用 HTML 标记和 JavaBean 标记来显示数据。
 控制器:一个或多个 Servlet 对象,根据视图提交的请求进行控制,即将请求转发给处理业务逻辑的 JavaBean,并将处理结果存放到实体模型 JavaBean 中,输出给视图显示。

在这里插入图片描述

二、 SpringMVC 简介

在这里插入图片描述

1 什么是 SpringMVC

SpringMVC是一个基于MVC模式的Web框架,是Spring框架的一个模块 。它以SpringIOC容器为基础,并利用容器的特性来简化它的配置,所以 SpringMVC 和 Spring 可直接整合使用。SpringMVC 对 MVC 流程进行了封装,屏蔽掉很多底层代码,让开发者可以更加轻松快捷的完成基于 MVC 模式的 Web 开发。

2 SpringMVC 中重要的组件

DispatcherServlet:前端控制器,接受所有请求。
HandlerMapping:处理器映射器,根据配置的映射规则,找到对应的处理器。
HandlerAdapter:处理器适配器,执行处理器中处理请求的方法。
ViewResolver:视图解析器,定位视图。

3 Spring MVC 工作流程

在这里插入图片描述

配置文件在SpringMVC框架启动时解析

Spring MVC 的工作流程如下:
 客户端请求提交到 DispatcherServlet。
 由 DispatcherServlet 控制器通过 HandlerMapping,找到处理请求的 Controller。
 DispatcherServlet 将请求提交到 Controller。
 Controller 调用业务逻辑处理后返回 ModelAndView。
 DispatcherServlet 通过 ViewResolver 视图解析器,找到 ModelAndView 指定的视图。
 视图负责渲染并将结果显示到客户端。

三、 SpringMVC 的基本使用

1 Jar 包依赖

Spring 核心容器模块
spring-beans-5.2.7.RELEASE.jar
spring-context-5.2.7.RELEASE.jar
spring-core-5.2.7.RELEASE.jar
spring-expression-5.2.7.RELEASE.jar
Commons-Loggin 日志
commons-logging-1.2.jar
Spring AOP 模块
spring-aop-5.2.7.RELEASE.jar
SpringWeb 模块
spring-web-5.2.7.RELEASE.jar
SpringWebMVC 模块
spring-webmvc-5.2.7.RELEASE.jar
Servlet
servlet-api.jar

2 搭建环境

2.1创建项目

缺少schema/beans的约束文件

在这里插入图片描述

解决办法:

复制这个URI添加约束文件

约束文件位置:D:\360MoveData\Users\admin\Desktop\编程笔记\JAVA 笔记\第六阶段资料\第二章\软件\spring-5.2.7.RELEASE-dist\spring-framework-5.2.7.RELEASE\schema\beans\spring-beans.xsd

在这里插入图片描述

web项目添加jar包还得点击Artifacts把jar包添加到WEB-INF下
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.2创建 springMVC 配置文件

放到项目的SRC目录下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">
</beans>

3 配置前端控制器

修改 web.xml

<!--前端控制器启动时会扫描springmvc的配置文件,如果未指定springMVC的配置文件及名称,那么前端控制器
默认会去WEB-INF目录中查找一个名称为‘springmvc’-servlet.xml的配置文件(springmvc是<serlet-name>标签中给的值-->

项目的SRC目录下的所有资源未来会被放到classes目录下,而classes目录指的就是classpath

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

    <!--配置SpringMVC的前端控制器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--前端控制器启动时会扫描springmvc的配置文件,如果未指定springMVC的配置文件及名称,那么前端控制器
        默认会去WEB-INF目录中查找一个名称为‘springmvc’-servlet.xml的配置文件(springmvc是<serlet-name>标签中给的值-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--项目的SRC目录下的所有资源未来会被放到classes目录下,而classes目录指的就是classpath-->
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--自启动Servlet,前端控制器这个Servlet要在项目时启动时就被实例化等着处理请求,这个Servlet的创建不依赖于请求而是项目启动-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--对于前端控制器所拦截的url一般配置为 / ,表示除了jsp以外的资源(请求)都会被这个Servlet拦截 / :无法拦截jsp
        而前端控制器的作用就是拦截所有的请求,然后根据请求的URI去查找未来让哪个控制器处理请求
        不写  /* 拦截所有资源是因为在使用springmvc框架时jsp不会放到web目录下,因为放到web目录下的jsp可以直接被访问,
        为了jsp的安全会把jsp放到WEB-INF目录中,WEB-INF中所有资源客户端无法直接访问,如果将jsp放到WEB-INF下未来访问是需要控制器控制的-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

4 创建 Controller 处理请求

4.1创建 Controller

在springmvc中处理请求的控制器不再是Servlet而是Controller

在这里插入图片描述

package com.bjsxt.web.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

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

public class DemoController implements Controller
{
   

    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
   
        ModelAndView modelAndView = new ModelAndView();
        //指定要跳转的视图
        modelAndView.setViewName("/index.jsp");
        //向视图中展示数据      param1:key  param2:value
        modelAndView.addObject("msg", "Hello SpringMVC");
        return modelAndView;
    }
}

web目录下的所有资源未来都会放到项目的根目录下

4.2配置 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置Controller    通过id属性或者name属性将一个URI绑定到Controller上-->
    <!--当浏览器请求/demo这个URI时DemoController的handleRequest()方法就会被执行-->
    <bean id="/demo" class="com.bjsxt.web.controller.DemoController"/>

</beans>

实现效果,说明控制器DemoController的handleRequest()方法可以处理 /demo 请求

在这里插入图片描述

四、 SpringMVC 基于注解的使用方式

在 SpringMVC 的基本使用中我们是以传统方式创建的控制器,它需要实现 Controller 接口。传统风格的控制器不仅需要在配置文件中配置映射,而且只能编写一个处理方法,不够灵活。一个控制器只有一个handleRequest方法
使用基于注解的控制器具有以下两个优点:
 在基于注解的控制器类中可以编写多个处理方法,进而可以处理多个请求,这就允许将
相关的操作编写在同一个控制器类中,从而减少控制器类的数量,方便以后的维护。
 基于注解的控制器不需要在配置文件中部署映射,仅需要使用 @RequestMapping 注解
就可以将一个 URI 绑定到类或方法上。

1 注解介绍

1.1@Controller

@Controller 注解用于指定 Bean 对象为控制器。

1.2@RequestMapping

@RequestMapping 用于将一个 URI 绑定到类(控制器类)上或类的方法中。

2 注解使用

2.1创建项目

在这里插入图片描述

2.2配置前端控制器
<?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>
        <!--指定springmvc配置文件的位置及名称-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--设置前端控制器自启动-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--拦截所有请求不包括jsp-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
2.3创建控制器
package com.bjsxt.web.controller;

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

@Controller//表示当前bean对象是一个控制器
//访问格式:http://localhost:8080/springmvcanndemo/suibian/ann
@RequestMapping("/suibian")//当我们请求这个控制器中所有的URI时前面都要加个suibian的前缀
public class AnnController {
   

    //访问格式:http://localhost:8080/springmvcanndemo/ann当发送这样的请求时请求会被annDemo方法拦截
    @RequestMapping(name = "/ann")//绑定URI 路径  /   可加可不加
    public ModelAndView annDemo(){
   
        ModelAndView modelAndView = new ModelAndView();
        /*设置需要跳转的视图*/
        modelAndView.setViewName("/index.jsp");
        /*向视图中传递数据*/
        modelAndView.addObject("msg", "Hello 临江仙");
        return modelAndView;
    }

}
2.4配置注解扫描

得开启Context命名空间

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

//配置注解扫描
<context:component-scan base-package="com.bjsxt.web.controller"/>
    
</beans>
<?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>
        <!--指定springmvc配置文件的位置及名称-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--设置前端控制器自启动-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--拦截所有请求不包括jsp-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
package com.bjsxt.web.controller;

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

@Controller//表示当前bean对象是一个控制器
//访问格式:http://localhost:8080/springmvcanndemo/suibian/ann
@RequestMapping("/suibian")//当我们请求这个控制器中所有的URI时前面都要加个suibian的前缀
public class AnnController {
   

    //访问格式:http://localhost:8080/springmvcanndemo/ann当发送这样的请求时请求会被annDemo方法拦截
    @RequestMapping("/ann")//绑定URI 路径  /   可加可不加
    public ModelAndView annDemo(){
   
        ModelAndView modelAndView = new ModelAndView();
        /*设置需要跳转的视图*/
        modelAndView.setViewName("/index.jsp");
        /*向视图中传递数据*/
        modelAndView.addObject("msg", "Hello 临江仙");
        return modelAndView;
    }

}

实现效果:

在这里插入图片描述

3 配置注解驱动

在基于注解方式开发控制器时,需要添加mvc:annotation-driven/标签,它是启用 MVC注解的钥匙。如果没有使用这个标签,而仅仅是使用context:component-scan/标签扫描并注册了相关的控制器,那么仅是@Controller @RequestMapping 基本功能的注解可以使用除此以外的相关的注解并不能使用。
mvc:annotation-driven/的作用是提供扩展功能的。
它的处理类 AnnotationDrivenBeanDefinitionParser 会注册很多基于注解开发时所用到的
Bean 对 象 到 容 器 中 。 其 中 包 含 RequestMappingHandlerMapping(处理器映射器) 、(RequestMappingHandlerAdapter(处理器适配器) 与 ExceptionHandlerExceptionResolver(异常解析器) 三个 bean。

3.1添加 mvc 命名空间
xmlns:mvc="http://www.springframework.org/schema/mvc"
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
3.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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">

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

    <!--配置注解扫描      只能扫描解析@Controller @RequestMapping 基本功能的注解-->
    <context:component-scan base-package="com.bjsxt.web.controller"/>

</beans>

五、 获取请求参数

在 Servlet 中我们通过 request.getParameter(name)方法获取请求参数。该方式存在两个问题:

 请求参数较多时会出现代码冗余的显现。
 与容器紧耦合。

在 SpringMVC 中可以使用 HttpServletRequest 对象获取请求数据,同时还提供了参数注入的方式用于获取请求数据。
SpringMVC 参数注入的优点:
 简化参数接收形式(不需要调用任何方法。需要什么参数, 就在控制器方法中提供什么参数)。
 参数类型不需要自己转换了。如果类型不符会抛出 400 异常。自动做类型转换
 可将参数自动封装为对象。
 如果没有该参数对应的数据,可为该参数指定默认值。

如果出现400异常应该考虑是不是参数类型转换出现问题

1 通过 HttpServletRequest 对象获取请求数据

/**
 * 通过HTTPServletRequest对象获取请求参数
 *该方法在执行时springMVC会自动的注入request对象
 * @return
 */
@RequestMapping("/getData")//URI的绑定
public ModelAndView getRequestParameter(HttpServletRequest request) {
   
    String username = request.getParameter("name");
    //封装到ModelAndView然后跳转到index.jsp展示
    ModelAndView modelAndView = new ModelAndView();
    //指定跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递的数据
    modelAndView.addObject("username", username);
    return modelAndView;
}

index.jsp

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/10/27
  Time: 10:19
  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>
  <%--通过EL表达式取出msg的值--%>
  ${msg}
  <hr/>
  ${username}
  </body>
</html>

在这里插入图片描述

给定参数的key一定要和处理请求方法的参数列表的参数名一致

在这里插入图片描述

2 通过参数注入获取请求参数

2.1注入多参数
/**
 * 通过SpringMVC参数注入方式获取请求参数————注入多参数
 * @param username
 * @param userage
 * @return
 */
@RequestMapping("/addUsers")//绑定URI
public ModelAndView addUsers(String username,int userage){
   //定义参数列表
    ModelAndView modelAndView = new ModelAndView();
    //设置跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递数据
    modelAndView.addObject("name", username);
    modelAndView.addObject("age", userage);
    return modelAndView;
}

index.jsp

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/10/27
  Time: 10:19
  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>
  <%--通过EL表达式取出msg的值--%>
  ${msg}
  <hr/>
  ${username}
  <hr/>
  ${name}&nbsp;&nbsp;${age}
  </body>
</html>

请求中参数的key一定要和参数列表的参数名一致

在这里插入图片描述

在这里插入图片描述

2.2@RequestParam 注解

@RequestParam:将请求参数绑定到控制器的方法参数上。
value:参数名(当请求参数的key和方法参数列表的参数名不匹配时需要用到)
required:是否包含该参数,默认为 true,表示该请求路径中必须包含该参数,如果不包含就报错。
defaultValue:默认参数值,如果设置了该值,required=true 将失效,自动改为 false,如果没有传该参数,就使用默认值

/**
 * @RequestParam使用
 * @param username
 * @param userage
 * @return
 */
@RequestMapping("/addUsers2")//绑定URI value是@RequestParam是默认属性   将请求参数name这个key的值注入到String类型的username这个参数中
public ModelAndView addUsers2(@RequestParam(value = "name",required = true,defaultValue = "GSG9") String username, @RequestParam("age") int userage){
   //定义参数列表
    ModelAndView modelAndView = new ModelAndView();
    //设置跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递数据
    modelAndView.addObject("name", username);
    modelAndView.addObject("age", userage);
    return modelAndView;
}

在这里插入图片描述

加了required属性并且属性值为true就必须给这个属性对应的参数,否则报错 400错误:参数缺失

在这里插入图片描述

在这里插入图片描述

如果required属性值为false请求中不给参数也没问题,属性默认值为true

在这里插入图片描述

在这里插入图片描述

如果请求中没有包含该参数则通过defaultValue给定默认值,一旦使用了defaultValue属性会自动将required属性由true改为false

在这里插入图片描述

在这里插入图片描述

2.3注入集合参数

在 SpringMVC 请求参数注入中,如果有多个请求参数的 name 相同,那么可以使用 String[]或 List 集合来接收请求参数。如果使用的 List 类型需要在该参数前添加@RequestParam 注解,String[]则不需要。

2.3.1 创建页面
<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/10/28
  Time: 10:45
  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="suibian/addUsers3">
        用户姓名:<input type="text" name="username"/><br/>
        爱好:<br/>
        体育<input type="checkbox" value="Sport" name="userlike"/><br/>
        音乐<input type="checkbox" value="Music" name="userlike"/><br/>
        艺术<input type="checkbox" value="Art" name="userlike"/><br/>
        <input type="submit" value="OK"/>
    </form>
</body>
</html>
2.3.2 修改控制器

String数组

@RequestMapping("/addUsers3")//绑定URI
public ModelAndView addUsers3(String username, String[] userlike){
   //定义参数列表  参数名必须和CheckBox的name相同
    ModelAndView modelAndView = new ModelAndView();
    //设置跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递数据
    modelAndView.addObject("userlike", username);
    String temp = "";
    for(String str:userlike){
   
        temp += str + " ";
    }
    modelAndView.addObject("age", temp);
    return modelAndView;
}

在这里插入图片描述

list集合

@RequestMapping("/addUsers3")//绑定URI
//如果用list这种集合类型即便是参数名和form表单中name属性值相同也需要加@RequestParam注解的,否则请求时报异常
public ModelAndView addUsers3(String username, @RequestParam List<String> userlike) {
   
    ModelAndView modelAndView = new ModelAndView();
    //设置跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递数据
    modelAndView.addObject("userlike", username);
    String temp = "";
    for (String str : userlike) {
   
        temp += str + " ";
    }
    modelAndView.addObject("age", temp);
    return modelAndView;
}

如果用list这种集合类型即便是参数名和form表单中name属性值相同也需要加@RequestParam注解的,否则请求时报异常

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.4注入对象参数

在 SpringMVC 的请求参数注入中,可以使用注入 POJO 方式来接收请求参数。

要求:请求参数的 name 必须与 POJO 的属性名相同。

2.4.1 注入单个对象
2.4.1.1 创建 POJO
package com.bjsxt.pojo;

import java.util.List;

public class Users {
   
    private String username;//参数名必须和form表单中name属性值相同
    private List<String> userlike;

    public String getUsername() {
   
        return username;
    }

    public void setUsername(String username) {
   
        this.username = username;
    }

    public List<String> getUserlike() {
   
        return userlike;
    }

    public void setUserlike(List<String> userlike) {
   
        this.userlike = userlike;
    }
}

页面的提交路径改变了

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/10/28
  Time: 10:45
  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="suibian/addUsers4">
        用户姓名:<input type="text" name="username"/><br/>
        爱好:<br/>
        体育<input type="checkbox" value="Sport" name="userlike"/><br/>
        音乐<input type="checkbox" value="Music" name="userlike"/><br/>
        艺术<input type="checkbox" value="Art" name="userlike"/><br/>
        <input type="submit" value="OK"/>
    </form>
</body>
</html>
2.4.1.2 修改控制器
/**
 * 通过注入POJO的方式实现接收请求参数
 * 可以继续增加参数列表中的内容继续注入非POJO实体中包含的属性
 * @param users
 * @return
 */
@RequestMapping("/addUsers4")//绑定URI
public ModelAndView addUsers4(Users users) {
   
    ModelAndView modelAndView = new ModelAndView();
    //设置跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递数据
    modelAndView.addObject("userlike", users.getUsername());
    String temp = "";
    for (String str : users.getUserlike()) {
   
        temp += str + " ";
    }
    modelAndView.addObject("age", temp);
    return modelAndView;
}

在这里插入图片描述

2.4.2 注入关联对象

SpringMVC 可以根据对象的关联关系实现请求参数的注入。

2.4.2.1 创建 POJO
package com.bjsxt.pojo;

public class Address {
   
    private String phonenumber;
    private String postcode;

    public String getPhonenumber() {
   
        return phonenumber;
    }

    public void setPhonenumber(String phonenumber) {
   
        this.phonenumber = phonenumber;
    }

    public String getPostcode() {
   
        return postcode;
    }

    public void setPostcode(String postcode) {
   
        this.postcode = postcode;
    }

    @Override
    public String toString() {
   
        return "Address{" +
                "phonenumber='" + phonenumber + '\'' +
                ", postcode='" + postcode + '\'' +
                '}';
    }
}
package com.bjsxt.pojo;

import java.util.List;

public class Users {
   
    private String username;//参数名必须和form表单中name属性值相同
    private List<String> userlike;

    //建立关联关系
    private Address address;

    public Address getAddress() {
   
        return address;
    }

    public void setAddress(Address address) {
   
        this.address = address;
    }

    public String getUsername() {
   
        return username;
    }

    public void setUsername(String username) {
   
        this.username = username;
    }

    public List<String> getUserlike() {
   
        return userlike;
    }

    public void setUserlike(List<String> userlike) {
   
        this.userlike = userlike;
    }

    @Override
    public String toString() {
   
        return "Users{" +
                "username='" + username + '\'' +
                ", userlike=" + userlike +
                '}';
    }
}
2.4.2.2 创建页面
<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/10/28
  Time: 10:45
  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="suibian/addUsers5">
        用户姓名:<input type="text" name="username"/><br/>
        爱好:<br/>
        体育<input type="checkbox" value="Sport" name="userlike"/><br/>
        音乐<input type="checkbox" value="Music" name="userlike"/><br/>
        艺术<input type="checkbox" value="Art" name="userlike"/><br/>
        地址:<br/><%--address是users对象所关联对象的属性名这时SpringMVC会帮助创建Address对象并且会把电话号码Input里面的值注入到address对象的phonenumber属性中--%>
        电话号码:<input type="text" name="address.phonenumber"/>
        邮编:<input type="text" name="address.postcode"/>
        <input type="submit" value="OK"/>
    </form>
</body>
</html>
2.4.2.3 修改控制器
@RequestMapping("/addUsers5")//绑定URI
public ModelAndView addUsers5(Users users) {
   
    ModelAndView modelAndView = new ModelAndView();
    //设置跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递数据
    modelAndView.addObject("user", users.toString());
    modelAndView.addObject("address", users.getAddress().toString());
    return modelAndView;
}

访问addUsers2.jsp

在这里插入图片描述

2.4.3 向集合中注入对象

在 SpringMVC 中可以向一个集合属性中注入对象。

2.4.3.1 List 集合

2.4.3.1.1 修改 Users

package com.bjsxt.pojo;

import java.util.List;

public class Users {
   
    private String username;//参数名必须和form表单中name属性值相同
    private List<String> userlike;

    //建立关联关系
    private Address address;

    private List<Address> addressList;

    public List<Address> getAddressList() {
   
        return addressList;
    }

    public void setAddressList(List<Address> addressList) {
   
        this.addressList = addressList;
    }

    public Address getAddress() {
   
        return address;
    }

    public void setAddress(Address address) {
   
        this.address = address;
    }

    public String getUsername() {
   
        return username;
    }

    public void setUsername(String username) {
   
        this.username = username;
    }

    public List<String> getUserlike() {
   
        return userlike;
    }

    public void setUserlike(List<String> userlike) {
   
        this.userlike = userlike;
    }

    @Override
    public String toString() {
   
        return "Users{" +
                "username='" + username + '\'' +
                ", userlike=" + userlike +
                '}';
    }
}

2.4.3.1.2 创建页面

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/10/28
  Time: 10:45
  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="suibian/addUsers6">
        用户姓名:<input type="text" name="username"/><br/>
        爱好:<br/>
        体育<input type="checkbox" value="Sport" name="userlike"/><br/>
        音乐<input type="checkbox" value="Music" name="userlike"/><br/>
        艺术<input type="checkbox" value="Art" name="userlike"/><br/>
        地址:<br/>
        <%--SpringMVC在完成请求参数注入时发现addressList属性对应的是一个list集合
        springMVC会帮助创建Address对象并且把电话和邮编放到list下标为0的Address的属性中--%>
        电话号码:<input type="text" name="addressList[0].phonenumber"/>
        邮编:<input type="text" name="addressList[0].postcode"/>
        电话号码1:<input type="text" name="addressList[1].phonenumber"/>
        邮编1:<input type="text" name="addressList[1].postcode"/>
        <input type="submit" value="OK"/>
    </form>
</body>
</html>

2.4.3.1.3 修改控制器

@RequestMapping("/addUsers6")//绑定URI
public ModelAndView addUsers6(Users users) {
   
    ModelAndView modelAndView = new ModelAndView();
    //设置跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递数据
    modelAndView.addObject("user", users.toString());
    modelAndView.addObject("address", users.getAddressList());//list会自行调用toString()方法
    return modelAndView;
}

实现效果

在这里插入图片描述

在这里插入图片描述

2.4.3.2 Map 集合

2.4.3.2.1 修改 Users

package com.bjsxt.pojo;

import java.util.List;
import java.util.Map;

public class Users {
   
    private String username;//参数名必须和form表单中name属性值相同
    private List<String> userlike;

    //建立关联关系
    private Address address;

    private List<Address> addressList;

    private Map<String, Address> addressMap;

    public Map<String, Address> getAddressMap() {
   
        return addressMap;
    }

    public void setAddressMap(Map<String, Address> addressMap) {
   
        this.addressMap = addressMap;
    }

    public List<Address> getAddressList() {
   
        return addressList;
    }

    public void setAddressList(List<Address> addressList) {
   
        this.addressList = addressList;
    }

    public Address getAddress() {
   
        return address;
    }

    public void setAddress(Address address) {
   
        this.address = address;
    }

    public String getUsername() {
   
        return username;
    }

    public void setUsername(String username) {
   
        this.username = username;
    }

    public List<String> getUserlike() {
   
        return userlike;
    }

    public void setUserlike(List<String> userlike) {
   
        this.userlike = userlike;
    }

    @Override
    public String toString() {
   
        return "Users{" +
                "username='" + username + '\'' +
                ", userlike=" + userlike +
                '}';
    }
}

2.4.3.2.2 创建页面

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/10/28
  Time: 10:45
  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="suibian/addUsers7">
        用户姓名:<input type="text" name="username"/><br/>
        爱好:<br/>
        体育<input type="checkbox" value="Sport" name="userlike"/><br/>
        音乐<input type="checkbox" value="Music" name="userlike"/><br/>
        艺术<input type="checkbox" value="Art" name="userlike"/><br/>
        地址:<br/>
        <%--中括号指定当前map的key,input域的值会被放到map的key为one的Address对象的属性下--%>
        电话号码:<input type="text" name="addressMap['one'].phonenumber"/>
        邮编:<input type="text" name="addressMap['one'].postcode"/>
        电话号码1:<input type="text" name="addressMap['two'].phonenumber"/>
        邮编1:<input type="text" name="addressMap['two'].postcode"/>
        <input type="submit" value="OK"/>
    </form>
</body>
</html>

2.4.3.2.3 修改控制器

@RequestMapping("/addUsers7")//绑定URI
public ModelAndView addUsers7(Users users) {
   
    ModelAndView modelAndView = new ModelAndView();
    //设置跳转视图的名称
    modelAndView.setViewName("/index.jsp");
    //设置传递数据
    modelAndView.addObject("user", users.toString());
    //获取map的Entry类型
    Set<Map.Entry<String, Address>> set = users.getAddressMap().entrySet();
    modelAndView.addObject("address", set);//会自动调用set.toString()然后调用Map.Entry.tpString()然后再调用Address.toString(),这样Address的值就会都显示出来
    return modelAndView;
}

在这里插入图片描述

3 字符编码过滤器

在请求参数中如果含有中文,会出现乱码现象。

3.1Get 请求含有中文乱码解决方案

如果是Tomcat9用get请求即便是请求中有中文也不用管,如果是9以下的版本 在配置端口的Connector结点中添加一个 URLEncoding属性,值为utf-8

修改 Tomcat 的 server.xml 配置文件

在这里插入图片描述

3.2Post 请求含有中文乱码解决方案

出现乱码了

在这里插入图片描述

在这里插入图片描述

修改web.xml文件

<!--配置请求编码-->
<filter>
    <filter-name>encodeFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值