JavaEE程序设计【十一】

一、初识SpringMVC


SpringMVC框架是Spring 框架的一部分,可以方便的利用Spring所提供的其他功能。

1、实现Controller接口和配置XML方式实现(用于理解,开发不用)

1.在web.xml中,配置Spring MVC的前端控制器DispatcherServlet。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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:springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

这里说明一下XML的配置,因为之前JSP使用注解,所以很少配置XML

  • <load-on-startup>1</load-on-startup>“1”表示容器在启动时立即加载该Servlet
  • <init-param>是给DispatcherServlet对象注入Spring配置文件。
  • < url-pattern > / </ url-pattern > 不会匹配到.jsp, 只针对我们编写的请求;即:.jsp 不会进入spring的 DispatcherServlet类 。< url-pattern > /* </ url-pattern >会匹配 *.jsp,会出现返回 jsp视图 时再次进入spring的DispatcherServlet 类,导致找不到对应的controller所以报404错。

客户端请求—>URL解析—>XM使用<url-pattern>/</url-pattern>配置了解到拦截所有的请求—>根据<servlet-name>springmvc</servlet-name>找到相应的servlet进行处理。

1
2
3
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>

由此可知,SpringMVC中所有的请求都被DispatcherServlet拦截处理。

而在之前的JSP设计中,我们一个请求都需要一个Servlet进行处理,同时在web.XML中配置相应的拦截和映射处理,使得每个请求找到相应的servlet进行处理。

==这里体现的就是SpringMVC的一个特点了,增加”一层DispatcherServlet”在servlet映射处理上,进行自动配置,减少我们的工作量。同时也是一个思想“没有什么是增加一个‘父层’解决不了的,有就行2层”==

2.创建控制器类,并实现Controller接口。

1
2
3
4
5
6
7
8
9
10
11
public class FirstController implements Controller {

@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
ModelAndView modelAndView = new ModelAndView();/*创建ModelAndView对象*/
modelAndView.addObject("msg","第一个SpringMVC程序!");/*添加返回信息*/
modelAndView.setViewName("/WEB-INF/jsp/first.jsp"); /*设置逻辑视图名*/
return modelAndView;
}
}

3.设置Spring配置文件,注册bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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">

<!-- 处理器映射器,将处理器Handle的name作为url进行查找 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 处理器适配器,配置对处理器中handleRequest()方法的调用-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />


<bean name="/first" class="cn.edu.ccc.ch11.c.FirstController"></bean>

</beans>

BeanNameUrlHandlerMapping(可换成其他的mapping这个是通过beanname查找匹配servlet)

4.编写JSP页面

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@page isELIgnored="false"%>
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
${msg}
</body>
</html>

关于EL表达式:注意Servlet版本,如果是Servlet 2.x,需要设置isELIgnored <%@page isELIgnored="false" %>

EL 全名为Expression Language,在本程序中的作用:

获取数据:${msg}${user.address.city}

EL表达式还有很多功能,可另查阅学习

5.将ch11项目发布到Tomcat中,并启动Tomcat服务器。在浏览器中访问

2、SpringMVC的工作流程

==只有虚线是我们需要编写的部分,其他都由Spring自动完成==

简要分析执行流程

  1. DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。

    我们假设请求的url为 : http://localhost:8080/SpringMVC/hello

    如上url拆分成三部分:

    http://localhost:8080服务器域名

    SpringMVC部署在服务器上的web站点(发布时容器不配置有可能为空。)

    hello表示控制器

    通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。

  2. HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。

  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。

  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。

  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。

  6. Handler让具体的Controller执行。

  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。

  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。

  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet。

  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。

  12. 最终视图呈现给用户。

粗略:DispatcherServlet拦截所有的请求,自动寻找我们配置的controller,并运行,返回给DispatcherServlet,然后DispatcherServlet将controller中得到的数据和视图名交给ViewResolver进行渲染显示给用户。 这些都是Spring帮我们做,我们只需要①配置一次web.xml 配置DispatcherServlet拦截所有请求②配置spring配置文件,添加处理器映射器、处理器适配器、视图解析器(目前版本自动添加可忽略不配,若需要拼装只需要配置视图解析器)和我们的controller(使用注解则不用,而是开启扫描和其他配置之后讲)③ 专心进行我们的controller业务逻辑编写即可

SpringMVC中HandlerMapping和HandlerAdapter详解(适配器模式)

==关于HandlerMapping和HandlerAdapter,需要了解适配器模式。再来理解是为何。这里浅显知道是Spring用来自动为请求寻找相应的servlet即controller进行处理。之后再来深入学习==

==使用springMVC必须配置的三大件:==

==处理器映射器、处理器适配器、视图解析器==

==通常,我们只需要手动配置视图解析器,而处理器映射器处理器适配器只需要开启注解驱动即可,而省去了大段的xml配置(原来我们使用xml方法配置的话一个servlet就需要在xml中配置一个)==

3、核心类

(1)DispatcherServlet

DispatcherServlet的全名是org.springframework.web.servlet.DispatcherServlet,它在程序中充当着前端控制器的角色。在使用时,只需将其配置在项目的web.xml文件中,

1
2
3
4
5
6
7
8
9
<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:springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

如果没有通过<init-param>元素配置,则应用程序会默认去WEB-INF目录下寻找以servletName-servlet.xml方式命名的配置文件,这里的servletName指下面的springmvc

如果<init-param>元素存在并且通过其子元素配置了Spring MVC配置文件的路径,则应用程序在启动时会加载配置路径下的配置文件

(2)ViewResolver

Spring MVC中的视图解析器负责解析视图。可以通过在配置文
件中定义一个ViewResolver来配置视图解析器,配置示例如下:

1
2
3
4
5
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>

上述代码中,定义了一个视图解析器,并设置了视图的前缀和后缀属性。这样设置后,方法中所定义的view路径将可以简化。例如,入门案例中的逻辑视图名只需设置为“first”,相当于“/WEB-INF/jsp/first.jsp”,视图解析器会自动的增加前缀和后缀。

(3)@Controller

org.springframework.stereotype.Controller注解类型用于指示Spring类的实例是一个控制器,其注解形式为@Controller。

该注解在使用时不需要再实现Controller接口,只需要将@Controller注解加入到控制器类上,然后通过Spring的扫描机制找到标注了该注解的控制器即可。

1
2
3
4
5
6
7
package cn.edu.ccc.ch12.controller;
import org.springframework.stereotype.Controller;
...
@Controller
public class FirstController{
...
}

在Spring MVC的配置文件中添加相应的扫描配置信息,一个完整的配置文件示例如下:

1
2
3
4
5
6
7
8
9
<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="cn.edu.ccc" />
</beans>

(4)@RequestMapping

Spring通过@Controller注解找到相应的控制器类后,还需要知道控制器内部对每一个请求是如何处理的,使用@RequestMapping注解类型,它用于映射一个请求或一个方法。使用时,可以标注在一个方法或一个类上。

标注在方法上:

1
2
3
4
5
6
@Controller
public class FirstController{
@RequestMapping(value="/firstController")
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse resp) {
......
return mav;}

此时,可以通过地址:http://localhost:8080/ch12/firstController访问该方法

标注在类上:该类中的所有方法都将映射为相对于类级别的请求,表示该控制器所处理的所有请求都被映射到value属性值所指定的路径下。

1
2
3
4
5
6
7
8
9
@Controller
@RequestMapping(value="/hello")
public class FirstController{
@RequestMapping(value="/firstController")
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) {
...
return mav;
}
}

由于在类上添加了@RequestMapping 注解,并且其value 属性值为“/hello” ,所以上述代码方法的请求路径将变为:http://localhost:8080/ch12/hello/firstController

组合注解:

请求处理方法的参数和返回类型:

==由于ModelAndView 类型未能实现数据与视图之间的解耦,所以在企业开发时,方法的返回类型通常都会使用String。String用来跳转视图,而其他的数据用model带回==

String类型除了可以返回上述代码中的视图页面外,还可以进行重定向与请求转发:

  • return "redirect:queryUser";
  • return "forward:editUser";

4、注解方式使用

1、配置项目里的web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<!-- 配置前端过滤器 -->
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 初始化时加载配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<!-- 表示容器在启动时立即加载Servlet PS:数字越小,启动越早-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

2.修改编写SpringMVC的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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">
<!-- 配置处理器Handle,映射“/firstController”请求 -->
<context:component-scan base-package="cn.edu.ccc" />
<bean id="viewResolver" class=
"org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 设置后缀 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>

在类和方法上添加相应注解即可

1
2
3
4
5
6
7
8
9
10
@Controller
@RequestMapping(value="/hello")
public class FirstController{
@RequestMapping(value="/firstController")
public String handleRequest(HttpServletRequest request,
HttpServletResponse response, Model model) throws Exception {
model.addAttribute("msg", "这是我的第一个Spring MVC程序");
return "first";
}
}

二、数据绑定

在执行程序时, Spring MVC会根据客户端请求参数的不同,将请求消息中的信息以一定的方式转换并绑定到控制器类的方法参数中。这种将请求消息数据与后台方法参数建立连接的过程就是 Spring MVC中的数据绑定。

其实就是如何将前端的数据传到后端

Spring mvc是怎样完成的数据绑定?

在数据绑定过程中, Spring MVC框架会通过数据绑定组件( Data Binder)先将请求参数串的内容进行类型转换

然后将转换后的值赋给控制器类中方法的形参,这样后台方法就可以正确绑定并获取客户端请求携带的参数了.

1、简单数据绑定

(1)HttpServletRequest默认模式

1
2
3
4
5
6
7
8
9
10
@Controller
public class UserController {
@RequestMapping("/selectUser")
public String selectUser(HttpServletRequest request) {
String id = request.getParameter("id");
System.out.println(id);
request.setAttribute("id", id);
return "success";
}
}
1
2
3
4
5
6
7
8
9
10
11
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>结果页面</title>
</head>
<body>
${id}
</body>
</html>

使用http://localhost:8080/ch13/selectUser?id=1即可测试得到id。

(2)Spring自动绑定基础数据类型

1
2
3
4
5
@RequestMapping("/findUser")
public String findUser(Integer id) {
System.out.println(id);
return "success";
}

使用http://localhost:8080/ch13/findUser?id=1也可以测试出,数据从前端传到了后端。

注意:参数名和后台控制器类方法中的形参名要一样,若不一样,需要使用@RequestParam(“前端属性名”)进行标注。但是一般不会自找麻烦,写一样的就可以了。

1
2
3
4
5
@RequestMapping("/findUser")
public String findUser(@RequestParam("id")Integer text) {
System.out.println(id);
return "success";
}

(3)Spring自动绑定绑定POJO类

1
2
3
4
5
6
public class User {
private Integer id; //用户id
private String username; //用户
private Integer password;//用户密码
……
}
1
2
3
4
5
6
7
8
9
@RequestMapping("/toRegister")
public String toRegister() {
return "register";
}
@RequestMapping("/registerUser")
public String registerUser(User user) {
System.out.println("注册的用户信息:"+user);
return "ok";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册</title>
</head>
<body>
<form action="registerUser" method="post">
用户名:<input type="text" name="username" /><br />
密&nbsp;&nbsp;&nbsp;码:<input type="text" name="password" /><br />
<input type="submit" value="注册"/>
</form>
</body>
</html>

访问http://localhost:8080/ch13/toRegister即可测试。

注意:前端属性名和POJO类属性名要一样!!

(4)绑定包装POJO类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Orders {
private Integer ordersId; // 订单编号
private User user; // 用户POJO,所属用户
public Integer getOrdersId() {
return ordersId;
}
public void setOrdersId(Integer ordersId) {
this.ordersId = ordersId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Controller
public class OrdersController {
/**
* 向订单查询页面跳转
*/
@RequestMapping("/tofindOrdersWithUser")
public String tofindOrdersWithUser( ) {
return "orders";
}
/**
* 查询订单和用户信息
*/
@RequestMapping("/findOrdersWithUser")
public String findOrdersWithUser(Orders orders) {
Integer orderId = orders.getOrdersId();
User user = orders.getUser();
String username = user.getUsername();
System.out.println("orderId="+orderId);
System.out.println("username="+username);
return "success";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>订单查询</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/findOrdersWithUser" method="post">
订单编号:<input type="text" name="ordersId" /><br />
所属用户:<input type="text" name="user.username" /><br />
<input type="submit" value="查询" />
</form>
</body>
</html>

访问http://localhost:8080/ch13/tofindOrdersWithUser即可测试。

注意:前端中POJO内部的属性需要使用后端对应【对象.属性】例如:user.username

(5)其他

一般情况下,使用基本数据类型和POJO类型的参数数据已经能够满足需求,然而有些特殊类型的参数是无法在后台进行直接转换的,但也有特殊数据类型无法直接进行数据绑定,必须先经过数据转换,例如日期数据。

①使用Converter

1.使用Converter进行数据转换,在src目录下创建一个cn.edu.ccc.ch13.convert包,在该包下创建日期转换类DateConverter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class DateConverter implements Converter<String, Date> {
// 定义日期格式
private String datePattern = "yyyy-MM-dd HH:mm:ss";
@Override
public Date convert(String source) {
// 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
try {
return sdf.parse(source);
} catch (ParseException e) {
throw new IllegalArgumentException(
"无效的日期格式,请使用这种格式:"+datePattern);
}
}
}

编写配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
......
<!-- 显示的装配自定义类型转换器 -->
<mvc:annotation-driven conversion-service="conversionService" />
<!-- 自定义类型转换器配置 -->
<bean id="conversionService" class=
"org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.edu.ccc.ch13.convert.DateConverter" />
</set>
</property>
</bean>
</beans>

创建一个日期控制器类DateController

1
2
3
4
5
6
7
8
9
10
11
@Controller
public class DateController {
/**
* 使用自定义类型数据绑定日期数据
*/
@RequestMapping("/customDate")
public String CustomDate(Date date) {
System.out.println("date="+date);
return "success";
}
}

访问:访问http://localhost:8080/chapter13/customDate?date= 2020-04-12 15:55:55。进行测试

②使用format
1
2
3
4
5
6
7
8
<!-- 自定义类型格式化转换器配置 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="cn.edu.ccc.ch13.convert.DateFormatter" />
</set>
</property>
</bean>

2、复杂数据绑定

实际开发中仍可能遇到一些比较复杂的数据绑定问题,比如数组的绑定集合的绑定,这在实际开发中也是十分常见的

(1)数组绑定

在实际开发时,可能会遇到前端请求需要传递到后台一个或多个相同名称参数的情况(如批量删除),此种情况采用前面讲解的简单数据绑定的方式显然是不合适的.针对上述这种情况,如果将所有同种类型的请求参数封装到一个数组中,后台就可以进行绑定接收了.

user.jsp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户列表</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/deleteUsers"
method="post">
<table width="20%" border=1>
<tr>
<td>选择</td>
<td>用户名</td>
</tr>
<tr>
<td><input name="ids" value="1" type="checkbox"></td>
<td>tom</td>
</tr>
<tr>
<td><input name="ids" value="2" type="checkbox"></td>
<td>jack</td>
</tr>
<tr>
<td><input name="ids" value="3" type="checkbox"></td>
<td>lucy</td>
</tr>
</table>
<input type="submit" value="删除"/>
</form>
</body>
</html>

在UserController中,编写接收批量删除用户的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RequestMapping("/toUser")
public String selectUsers( ) {
return "user";
}
/**
* 接收批量删除用户的方法
*/
@RequestMapping("/deleteUsers")
public String deleteUsers(Integer[] ids) {
if(ids !=null){
for (Integer id : ids) {
// 使用输出语句模拟已经删除了用户
System.out.println("删除了id为"+id+"的用户!");
}
}else{
System.out.println("ids=null");
}
return "success";
}

访问http://localhost:8080/ch13/toUser进行测试。

(2)集合绑定

但如果是批量修改用户操作的话,前端请求传递过来的数据可能就会批量包含各种类型的数据,如 Integer, String等.由于数组内容必须是一致的,所以针对上述这种情况,就可以使用集合数据绑定.即在包装类中定义一个包含用户信息类的集合,然后在接收方法中将参数类型定义为该包装类的集合.

在src目录下创建一个cn.edu.ccc.ch13.vo包,创建包装类UserVo封装用户集合属性:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 用户包装类
*/
public class UserVO {
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}

在UserController中,编写接收批量删除用户的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 向用户批量修改页面跳转
*/
@RequestMapping("/toUserEdit")
public String toUserEdit() {
return "user_edit";
}
/**
* 接收批量修改用户的方法
*/
@RequestMapping("/editUsers")
public String editUsers(UserVO userList) {
// 将所有用户数据封装到集合中
List<User> users = userList.getUsers();
// 循环输出所有用户信息
for (User user : users) {
// 如果接收的用户id不为空,则表示对该用户进行了修改
if(user.getId() !=null){
System.out.println("修改了id为"+user.getId()+
"的用户名为:"+user.getUsername());
}
}
return "success";
}

user_edit.jsp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<form action="${pageContext.request.contextPath }/editUsers"
method="post" id='formid'>
<table width="30%" border=1>
<tr><td>选择</td><td>用户名</td></tr>
<tr>
<td><input name="users[0].id" value="1" type="checkbox" /> </td>
<td>
<input name="users[0].username" value="tome" type="text" />
</td>
</tr>
<tr>
<td><input name="users[1].id" value="2" type="checkbox" /> </td>
<td>
<input name="users[1].username" value="jack" type="text" />
</td>
</tr>
</table>
<input type="submit" value="修改" />
</form>
</body>
</html>

3、解决中文乱码

SpringMVC给我们提供了一个过滤器 , 可以在web.xml中配置 .

1
2
3
4
5
6
7
8
9
10
11
12
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-----------------------本文结束 感谢阅读-----------------------
坚持原创技术分享,您的支持将鼓励我继续创作!恰饭^.^~