一、传值方式

(1)Map

Controller

@Controller
public class MyController {
@RequestMapping("first")
public String show(Map map){
// 把数据写到 request 域
map.put("name","大白");
map.put("age",20);
return "/result.jsp";
}
}

结果页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>结果页</h3>
${requestScope.name}
${requestScope.age}
</body>
</html>

(2)ModelMap

ModelMap 对象主要用于传递控制方法处理数据到结果页面,也就是说我们把结果页面上需要的数据放到ModelMap 对象中即可。

把数据写到 request 域。request对象的setAttribute方法的作用: 用来在一个请求过程中传递处理的数据。

使用方法与model一样。

(3)Model

Model 和 ModelMap 的实例都是 spirng mvc 框架来自动创建并作为控制器方法参数传入,用户无需自己创建

可以简单地将model的实现类理解成一个Map,Request级别的模型数据。

Model 是一个接口, 其实现类为 ExtendedModelMap,继承了ModelMap类。

方法介绍

① asMap
Map<String, Object> asMap();

将当前的 model 转换成 Map

发送请求页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/first">发送请求</a>
</body>
</html>

结果页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>结果页</h3>
${requestScope.name}
</body>
</html>

Controller

@Controller
public class MyController {
@RequestMapping("first")
public String show(Model model){
// 把数据写到 request 域
model.addAttribute("name","Hello World");
System.out.println(model.asMap());
return "/result.jsp";
}
}
② addAttribute
// 添加键值属性对
Model addAttribute(String attributeName, Object attributeValue);
// 以属性的类型为键添加属性
Model addAttribute(Object attributeValue);

注意:

① addAttribute(Object attributeValue) 默认的key是属性的类型首字母小写

② 如果model存在相同key,会被覆盖

请求页和 ① asMap 一样

结果页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>结果页</h3>
${requestScope.dog}
</body>
</html>

Controller

@Controller
public class MyController {
@RequestMapping("first")
public String show(Model model){
// 把数据写到 request 域
Dog mydog = new Dog();
mydog.setName("WC");
mydog.setColor("白色");
model.addAttribute("dogs",mydog);
// model.addAttribute(mydog); 相当于 model.addAttribute("dog",mydog);
model.addAttribute(mydog);
System.out.println(model.asMap());
return "/result.jsp";
}
}
③ addAllAttributes
// 将attributes中的内容复制到当前的model中,如果当前model存在相同内容,会被覆盖
Model addAllAttributes(Map<String, ?> attributes);
// 以集合中数据的类型首字母小写做为key,将所提供的Collection中的所有属性复制到这个Map中,如果有同类型会存在覆盖现象
Model addAllAttributes(Collection<?> attributeValues);

Controller

@Controller
public class MyController {
@RequestMapping("first")
public String show(Model model){
// 把数据写到 request 域
model.addAttribute("name","旺财"); HashMap<String, Object> map = new HashMap<>();
map.put("name","大白");
map.put("age",20);
model.addAllAttributes(map);
System.out.println(model.asMap());
// output:{name=大白, age=20} ArrayList<Object> list = new ArrayList<>();
list.add("小白");
list.add(20);
model.addAllAttributes(list);
System.out.println(model.asMap());
// output:{name=大白, age=20, string=小白, integer=20}
return "/result.jsp";
}
}
④ mergeAttributes
// 将attributes中的内容复制到当前的model中,如果当前model存在相同内容,不会被覆盖
Model mergeAttributes(Map<String, ?> attributes);

Controller

@Controller
public class MyController {
@RequestMapping("first")
public String show(Model model){
// 把数据写到 request 域
model.addAttribute("name","旺财"); HashMap<String, Object> map = new HashMap<>();
map.put("name","大白");
map.put("age",20);
model.mergeAttributes(map);
System.out.println(model.asMap());
// output:{name=旺财, age=20} return "/result.jsp";
}
}
⑤ containsAttribute
// 判断是否包含键为attributeName的值
boolean containsAttribute(String attributeName);

(4)ModelAndView

需要自己创建,既包含模型也包含视图

Controller

@Controller
public class MyController {
@RequestMapping("first")
public ModelAndView show(){
ModelAndView modelAndView = new ModelAndView();
// 把数据写到 request 域
modelAndView.addObject("name","大白");
modelAndView.addObject("age",20);
System.out.println(modelAndView.getModel());
modelAndView.setViewName("/result.jsp");
return modelAndView;
}
}

结果页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>结果页</h3>
${requestScope.name}
${requestScope.age}
</body>
</html>

(5)@SessionAttributes注解

将模型中的某个属性暂存到 HttpSession 中,以便多个请求之间可以共享这个属性,@SessionAttributes是标注在类上的。

value :通过指定key将model数据放到session域当中

type :把指定类型的模型数据放到session域当中

@Controller
@SessionAttributes(value = {"name","age"},types = String.class)
public class MyController {
@RequestMapping("first")
public String show(Model model){
// 把数据写到 request 域
model.addAttribute("name","大白");
model.addAttribute("age",20);
return "/result.jsp";
}
}

结果页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>结果页</h3>
${requestScope.name}
${requestScope.age}
${sessionScope.name}
${sessionScope.age}
</body>
</html>

(6)@SessionAttribute注解

使用 @SessionAttribute 来访问预先存在的全局会话属性

请求发送页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/first">发送请求</a> <a href="${pageContext.request.contextPath}/second">获取Session</a>
</body>
</html>

Controller

@Controller
@SessionAttributes(value = {"name","age"},types = String.class)
public class MyController {
@RequestMapping("first")
public String show(Model model){
model.addAttribute("name","大白");
model.addAttribute("age",20);
return "/result.jsp";
} @RequestMapping("second")
public String get(@SessionAttribute("name") String name, @SessionAttribute("age") Integer age){
// 把数据写到 request 域
System.out.println(name);
System.out.println(age);
return "/result.jsp";
}
}

(7)@ModelAttribute

① @ModelAttribute 修饰方法参数:修改处理方法的参数时,自动把该参数放到model当中

@Controller
public class MyController {
@RequestMapping("first")
// 使用JavaBean接收参数,如果方法参数中有 Model model,会自动的把JavaBean添加到 model中去
// 默认键名为JavaBean类型首字母小写,键名可以用@ModelAttribute设置
public String show(@ModelAttribute("mydog") Dog mydog, Model model){
// 把数据写到 request 域
System.out.println(model.asMap());
return "/result.jsp";
}
}

② @ModelAttribute 修饰方法

@ModelAttribute 修饰的方法,在对应的 @RequestMapping 映射方法执行之前,会自动调用,并且会自动的把model传入这个方法,允许提前传入一些model信息。

请求发送页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/first">发送请求</a>
<form action="${pageContext.request.contextPath}/first" method="post">
<p>name : <input type="text" name="name" value="小白"></p>
<p>color : <input type="text" name="color" value="白色"></p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>

Controller

@ModelAttribute 修饰的方法,在对应的 @RequestMapping 映射方法执行之前,允许提前传入一些model信息

@Controller
public class MyController { @ModelAttribute
public void init(Model model){
System.out.println("@ModelAttribute 自动调用");
model.addAttribute("age",5);
} @RequestMapping("first")
public String show(@ModelAttribute("mydog") Dog mydog, Model model){
System.out.println(model.asMap());
return "/result.jsp";
}
}

注意:

@ModelAttribute 修饰的方法中设置的 key 和 @RequestMapping 修饰的方法参数中的 key值相同时 @ModelAttribute中的会被“属性”覆盖。即 同名的属性名覆盖。

请求发送页不变,Controller如下

@Controller
public class MyController { @ModelAttribute
public void init(Model model){
System.out.println("@ModelAttribute 自动调用");
Dog dog = new Dog();
dog.setName("initName");
dog.setColor("initColor");
dog.setAge(20);
model.addAttribute("mydog",dog);
} @RequestMapping("first")
public String show(@ModelAttribute("mydog") Dog mydog, Model model){
System.out.println(model.asMap());
// outPut:{mydog=Dog{name='小白', color='白色', age=20}, ……}
return "/result.jsp";
}
}

注意:

@ModelAttribute 修饰的方法中,model 传进来之前,会把session域里的数据放到model中。

在 @ModelAttribute 里写的内容会覆盖session里的同名内容(“对象”覆盖)

请求发送

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/session">发送请求</a>
<form action="${pageContext.request.contextPath}/first" method="post">
<p>name : <input type="text" name="name" value="小白"></p>
<p>color : <input type="text" name="color" value="白色"></p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>

Controller

@Controller
@SessionAttributes(value = "")
public class MyController { @RequestMapping("session")
public String session(Model model){
Dog dog = new Dog();
dog.setName("sessionName");
dog.setColor("sessionColor");
dog.setAge(10);
model.addAttribute("dogs",dog);
return "/result.jsp";
} // model 传进来之前,会把session域里的数据放到model中。
// 在 @ModelAttribute 里写的内容会覆盖session里的同名内容(“对象”覆盖)
@ModelAttribute
public void init(Model model){
System.out.println("@ModelAttribute 自动调用");
Dog dog = new Dog();
dog.setName("initName");
dog.setColor("initColor");
model.addAttribute("dogs",dog);
} @RequestMapping("first")
public String show(@ModelAttribute("mydog") Dog mydog, Model model){
System.out.println(model.asMap());
// outPut:{dogs=Dog{name='initName', color='initColor', age=null}, mydog=Dog{name='小白', color='白色', age=null},……}
return "/result.jsp";
}
}

二、mvc:view-controller

当我们发送一个请求时,如果没有找到对应的mapping,则会对配置文件当中匹配 mvc:view-controller

请求发送页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/session">发送请求</a>
</body>
</html>

Controller

@Controller
public class MyController { }

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--注解扫描-->
<context:component-scan base-package="com.ssm"/> <mvc:view-controller path="session" view-name="/result.jsp"/>
</beans>

注意点

使用时要添加:

<mvc:annotation-driven/>

如果没有添加,@Controller 中的 @RequestMapping 将不能使用。

请求发送页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/session">发送请求</a>
<a href="${pageContext.request.contextPath}/first">发送请求</a>
</body>
</html>

Controller

@Controller
public class MyController {
@RequestMapping("first")
public String view(){
return "/result.jsp";
}
}

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--注解扫描-->
<context:component-scan base-package="com.ssm"/> <mvc:view-controller path="session" view-name="/result.jsp"/>
</beans>

点击第二个发送请求时,会报404错误

(1)默认情况下(不写 mvc:view-controller),DispatcherServlet (前端控制器)会自动注册以下三个类

0 = {HttpRequestHandlerAdapter@8252}

1 = {SimpleControllerHandlerAdapter@8253}

2 = {RequestMappingHandlerAdapter@8254}

RequestMappingHandlerAdapter 就是处理 @RequestMapping 的。

(2)写了 mvc:view-controller 后,DispatcherServlet (前端控制器)只会自动注册以下两个类

0 = {HttpRequestHandlerAdapter@8255}

1 = {SimpleControllerHandlerAdapter@8256}

缺少了 RequestMappingHandlerAdapter ,所以发送 @RequestMapping 的请求会报 404 未找到错误。

(3)添加了 <mvc:annotation-driven/> 后会自动注册那三个类。

三、mvc:annotation-driven

<mvc:annotation-driven /> 是一种简写形式

会自动注册三个Bean

  • RequestMappingHandlerMapping
  • RequestMappingHandlerAdapter
  • ExceptionHandlerExceptionResolver

并提供了:

  • 数据绑定支持,
  • @NumberFormatannotation支持,
  • @DateTimeFormat支持,
  • @Valid支持,读写XML的支持(JAXB),
  • 读写JSON的支持(Jackson)。

所以,一般我们都加上 <mvc:annotation-driven /> 。

四、SpringMVC 中的 form标签

简介

在使用SpringMVC的时候我们可以使用Spring封装的一系列表单标签,这些标签都可以访问到 ModelMap 中的内容。

作用

第一是它会自动的绑定来自Model中的一个属性值到当前form对应的实体对象;第二是它支持我们在提交表单的时候使用除GET和POST之外的其他方法进行提交,包括DELETE和PUT等

使用场景

当编辑时, 跳转到form表单页,传统模式要在跳转前先到数据库查询数据,然后进行表单数据回显。

使用form之前一定要保证有对应的bean,没有对应的bean时, 会自动以command为key到 request域中查询,当找不到的时候, 会报异常。

使用方式

User

package com.ssm.domain;

import lombok.Getter;
import lombok.Setter; import java.util.Arrays; @Setter @Getter
public class User {
private Integer id;
private String username;
private String password;
private String gender;
private Integer age;
private String[] hobby;
private Pet pet; @Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", hobby=" + Arrays.toString(hobby) +
", pet=" + pet +
'}';
}
}

Pet

package com.ssm.domain;

import lombok.Getter;
import lombok.Setter; @Setter @Getter
public class Pet {
private Integer id;
private String name; public Pet() {
} public Pet(Integer id, String name) {
this.id = id;
this.name = name;
} @Override
public String toString() {
return "Pet{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

发送请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/edit/2">发送更新请求</a>
</body>
</html>

处理请求

@RequestMapping("edit/{id}")
public String view(@PathVariable Integer id, Model model){
System.out.println(id);
/* 模拟数据库查询,准备数据 */
ArrayList<String> hobbyList = new ArrayList<>();
hobbyList.add("篮球");
hobbyList.add("足球");
hobbyList.add("排球");
hobbyList.add("乒乓球");
model.addAttribute("hobbys", hobbyList); ArrayList<Pet> petList = new ArrayList<>();
petList.add(new Pet(1,"狗"));
petList.add(new Pet(2,"猫"));
petList.add(new Pet(3,"鸟"));
petList.add(new Pet(4,"猪"));
model.addAttribute("pets",petList); User user = new User();
// 文本框
user.setId(id);
user.setUsername("user1");
user.setPassword("145263");
user.setAge(20);
// 单选框
user.setGender("男");
// 复选框
String[] hobby = new String[]{"篮球","足球","排球"};
user.setHobby(hobby);
// 下拉框
user.setPet(new Pet(2,"猫")); model.addAttribute("user",user);
return "/update.jsp";
}

创建表单页,引入标签库

引入标签库

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="fm" %>

update.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="fm" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>更新界面</h1>
<fm:form modelAttribute="user" action="${pageContext.request.contextPath}/update">
<p>用户Id : <fm:input path="id"/></p>
<p>用户名 : <fm:input path="username"/></p>
<p>密码 : <fm:input path="password"/></p>
<p>年龄 : <fm:input path="age"/></p>
<p>性别 : <fm:radiobutton path="gender" value="男" label="男"/>
<fm:radiobutton path="gender" value="女" label="女"/></p>
<p>爱好 : <fm:checkboxes path="hobby" items="${hobbys}"/></p>
<p>宠物 : <fm:select path="pet.id" items="${pets}" itemValue="id" itemLabel="name"/></p>
<p><input type="submit" value="更新"></p>
</fm:form>
</body>
</html>

处理请求

@RequestMapping("update")
public String update(User user){
System.out.println(user);
return "result.jsp";
}

result.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>结果页</h3>
${requestScope.user}
</body>
</html>

五、服务器表单校验

为什么后端要做表单的校验,如果只使用前端校验的话,当浏览器把JS给禁用掉,就校验不了啦

JSR

JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中 ,JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解,指定校验规则,并通过标准的验证接口对 Bean 进行验证。

Hibernate Validator

Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持其它的扩展注解。

使用时需要导入jar包

+ Hibernate-Validator
- classmate.jar
- hibernate-validator-5.jar
- hibernate-validator-annotation-processor-5.jar
- jboss-logging-3.1.1.jar
- validation-api-1.1.0.jar

常用校验规则

Bean Validation 中内置的约束

约束注解 说明
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式

Hibernate Validator 附加的约束

约束注解 说明
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

使用

① 导入jar包,在配置文件当中写上

<mvc:annotation-driven/>

② 在模型当中添加对应的校验规则

package com.ssm.domain;

import lombok.Getter;
import lombok.Setter;
import org.hibernate.validator.constraints.NotBlank; import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.Arrays; @Setter @Getter
public class User {
@NotNull(message = "ID不能为空")
private Integer id;
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "密码不能为空")
private String password;
private String gender;
@Max(value = 200, message = "年龄不正确")
@Min(value = 0, message = "年龄不正确")
private Integer age;
private String[] hobby;
private Pet pet; @Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", hobby=" + Arrays.toString(hobby) +
", pet=" + pet +
'}';
}
}

③ 在处理器方法的参数标记@valid注解即可

@RequestMapping("update")
public String update(@Valid User user, BindingResult result) {
System.out.println(user);
List<FieldError> fieldErrors = result.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println(fieldError.getField() + " : " + fieldError.getDefaultMessage());
}
return "result.jsp";
}

④ 错误信息页面回显

(1)使用form标签
<fm:errors path=""/>

请求发送页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/edit/2">发送更新请求</a>
</body>
</html>

user

package com.ssm.domain;

import lombok.Getter;
import lombok.Setter;
import org.hibernate.validator.constraints.NotBlank; import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.Arrays; @Setter @Getter
public class User {
@NotNull(message = "ID不能为空")
private Integer id;
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "密码不能为空")
private String password;
private String gender;
@Max(value = 200, message = "年龄不正确")
@Min(value = 0, message = "年龄不正确")
private Integer age;
private String[] hobby;
private Pet pet; @Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", hobby=" + Arrays.toString(hobby) +
", pet=" + pet +
'}';
}
}

Controller

package com.ssm.web.controller;

import com.ssm.domain.Pet;
import com.ssm.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List; @Controller
public class MyController {
ArrayList<String> hobbyList;
ArrayList<Pet> petList; @RequestMapping("edit/{id}")
public String view(@PathVariable Integer id, Model model) {
System.out.println(id);
/* 模拟数据库查询,准备数据 */
hobbyList = new ArrayList<>();
hobbyList.add("篮球");
hobbyList.add("足球");
hobbyList.add("排球");
hobbyList.add("乒乓球");
model.addAttribute("hobbys", hobbyList); petList = new ArrayList<>();
petList.add(new Pet(1, "狗"));
petList.add(new Pet(2, "猫"));
petList.add(new Pet(3, "鸟"));
petList.add(new Pet(4, "猪"));
model.addAttribute("pets", petList); User user = new User();
// 文本框
user.setId(id);
user.setUsername("user1");
user.setPassword("145263");
user.setAge(20);
// 单选框
user.setGender("男");
// 复选框
String[] hobby = new String[]{"篮球", "足球", "排球"};
user.setHobby(hobby);
// 下拉框
user.setPet(new Pet(2, "猫")); model.addAttribute("user", user);
return "/update.jsp";
} @RequestMapping("update")
public String update(@Valid User user, BindingResult result, Model model) {
System.out.println(user);
if (result.getErrorCount() != 0){
List<FieldError> fieldErrors = result.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println(fieldError.getField() + " : " + fieldError.getDefaultMessage());
}
model.addAttribute("hobbys", hobbyList);
model.addAttribute("pets", petList); return "/update.jsp";
} return "/result.jsp";
}
}

update.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="fm" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>更新界面</h1>
<fm:form modelAttribute="user" action="${pageContext.request.contextPath}/update">
<p>用户Id : <fm:input path="id"/> <fm:errors path="id" cssStyle="color: red"/></p>
<p>用户名 : <fm:input path="username"/> <fm:errors path="username" cssStyle="color: red"/> </p>
<p>密码 : <fm:input path="password"/> <fm:errors path="password" cssStyle="color: red"/></p>
<p>年龄 : <fm:input path="age"/> <fm:errors path="age" cssStyle="color: red"/></p>
<p>性别 : <fm:radiobutton path="gender" value="男" label="男"/>
<fm:radiobutton path="gender" value="女" label="女"/></p>
<p>爱好 : <fm:checkboxes path="hobby" items="${hobbys}"/></p>
<p>宠物 : <fm:select path="pet.id" items="${pets}" itemValue="id" itemLabel="name"/></p>
<p><input type="submit" value="更新"></p>
</fm:form>
</body>
</html>

结果页

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>结果页</h3>
${requestScope.user}
</body>
</html>
(2)使用原始表单错误信息写到Model中

SpringMVC(中)的更多相关文章

  1. SpringMvc中的数据校验

    SpringMvc中的数据校验 Hibernate校验框架中提供了很多注解的校验,如下: 注解 运行时检查 @AssertFalse 被注解的元素必须为false @AssertTrue 被注解的元素 ...

  2. 【Spring】SpringMVC中浅析Date类型数据的传递

    在控制器中加入如下代码: @InitBinder public void initBinder(ServletRequestDataBinder bin){ SimpleDateFormat sdf ...

  3. 详解SpringMVC中GET请求

    GET请求概述 GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接.URL的编码格式采用的是ASCII编码,而不是uniclde,所有的非ASCII字符都要编 ...

  4. SpringMVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  5. 如何在springMVC 中对REST服务使用mockmvc 做测试

    如何在springMVC 中对REST服务使用mockmvc 做测试 博客分类: java 基础 springMVCmockMVC单元测试  spring 集成测试中对mock 的集成实在是太棒了!但 ...

  6. springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序

    springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序 http://www.360doc.com/content/14/03 ...

  7. SpringMVC中使用Cron表达式的定时器

    SpringMVC中使用Cron表达式的定时器 cron(定时策略)简要说明 顺序: 秒 分 时 日 月 星期 年份 (7个参数,空格隔开各个参数,年份非必须参数) 通配符: , 如果分钟位置为* 1 ...

  8. SpringMVC中使用Json传数据

    在web项目中使用Json进行数据的传输是非常常见且有用的,在这里介绍下在SpringMVC中使用Json传数据的一种方法,在我的使用中,主要包括下面四个部分(我个人喜好使用maven这类型工具进行项 ...

  9. springmvc 中controller与jsp传值

    参考:springmvc 中controller与jsp传值 springMVC:将controller中数据传递到jsp页面 jsp中,死活拿不到controller中的变量. 花了半天,网上列出各 ...

  10. 在Springmvc中获取properties属性

    一些关键的属性一般都会拿出来作为配置,比如数据库连接等.在springmvc中也提供了获取property的类,比如@Value来获取.我接触spring很浅,基本上都是百度的问题解决方法,百度到@v ...

随机推荐

  1. TypeScript基础以及在Vue中的应用

    TypeScript推出已经很长时间了,在Angular项目中开发比较普遍,随着Vue 3.0的即将推出,TypeScript在Vue项目中使用也即将成为很大的趋势,笔者也是最近才开始研究如何在Vue ...

  2. Django:缓存及相关配置

    缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache ...

  3. 记录axios在IOS上不能发送的问题

    最近 遇到 了axios在IOS上无法发送的问题,测试 了两个 苹果 机,IOS10上不能发送,IOS12可以,百度了下,找到了解决方法.记录下吧 首先引入qs,这个安装axios也已经有了吧:然后在 ...

  4. iOS学习——NSLog输出各种类型

    在开发过程中,在调试过程中经常打印不出自己想要的数据格式,还时常报警告,所以整理了一下iOS中用NSLog打印各种数据类型的样式.整型占位符说明 : %d : 十进制整数, 正数无符号, 负数有 “- ...

  5. H3C 802.11网络的基本元素

  6. golang读写文件

    1. 标准输入输出 os提供了标准输入输出文件: Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin") Stdout = Ne ...

  7. 利用ansible书写playbook搭建HAProxy+Keepalived+PXC负载均衡和高可用的PXC环境续

    ansible.playbook.haproxy.keepalived.PXC haproxy+keepalived双主模式调度pxc集群 HAProxy介绍 反向代理服务器,支持双机热备支持虚拟主机 ...

  8. FriendlyCore overlayfs 挂载方式

    友善 friendlycore 挂载 overlayfs 过程: uboot 引导系统启动的时候加载 ramdisk.img  这个 cpio 格式的 initrd(虚拟文件系统). 注意: ramd ...

  9. .gitignore文件配置的内容为:

    /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project ...

  10. 【Selenium-WebDriver实战篇】ScreenRecorder的实际输出路径设置(转)

    参考:https://www.cnblogs.com/yongfeiuall/p/4134139.html 我们可以用以下方式在Selenium Webdriver中capture video. 基本 ...