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} ${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