SpringMVC的执行流程非常复杂,实际开发中非常简单,因为大部分组件不需要开发者自己创建、管理,只需要配置文件的方式完成配置即可。真正需要开发者进行处理和书写的代码是Handler和View。
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.3.5version>
dependency>
dependencies>
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 Applicationdisplay-name>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/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">
<context:component-scan base-package="com.wuzhou"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
beans>
package com.wuzhou.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Handler {
@RequestMapping("/index")
public String index(){
System.out.println("执行了index方法");
return "index";
}
}
SpringMVC是通过@RequestMapping注解将URL请求与业务方法进行映射,在Handler类的定义处以及方法定义处都可以添加该注解@RequestMapping,在类定义处添加,相当于客户端多了一层访问路径
@Controller注解是在类定义添加,将该类交给Ioc容器去管理(所谓的Ioc容器去管理,是因为在springmvc.xml文件中通过自动扫描包进行识别),同时使其成为一个控制器,可以接收客户端的请求
示例代码
package com.wuzhou.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/hello")
public class Handler {
@RequestMapping("/index")
public String index(){
System.out.println("执行了index方法");
return "index";
}
}
(1)value属性:指的是URL的实际请求地址,默认的情况下是可以省略不写的,即是@RequestMapping的默认值是省略
@RequestMapping("/index")
public String index(){
System.out.println("执行了index方法");
return "index";
}
等价于
@RequestMapping(value = "/index")
public String index(){
System.out.println("执行了index方法");
return "index";
}
(2)method属性:指定请求method的类型,常见的几种类型有GET、POST、PUT、DELETE等
@RequestMapping(value = "/index",method = RequestMethod.GET)
public String index(){
System.out.println("执行了index方法");
return "index";
}
上述代码index方法只能接收GET方式的请求
(3)params:指定请求中必须包含某些参数,否则无法调用该方法
@RequestMapping(value = "/index",method = RequestMethod.GET,params = {"name","id=10"})//其中id指定值为10,在url地址栏中id的属性值就应该是10,对于name的值可以是任意的
public String index(){
System.out.println("执行了index方法");
return "index";
}
上述代码请求中必须包含name和id的两个参数。与此同时,id的值必须是10,才能正确访问控制层的方法
@RequestMapping(value = "/index",method = RequestMethod.GET,params = {"name","id=10"})
//其中params中的参数名称是要与url请求地址的参数名称对应相同
public String index(@RequestParam("name") String nme,@RequestParam("id") Integer idNo){//@RequestParams()注解使用是在params注解属性中的参数名称不一样地时候需要添加进行赋给一个业务方法中的新参数名称,一般在业务逻辑方法中的参数名称是与params注解中的参数名称一样
System.out.println("name = " + nme);
System.out.println("id = " + idNo);
System.out.println("执行了index方法");
return "index";
}
上述代码表示将请求的参数name和id分别赋给了形参nme和idNo,同时完成了自动类型转换,(注意的是从http地址栏中以get方式进行参数赋值都是String字符串类型的),所以在上述中的id值为10实际上是String类型的,实际上是把String类型的数值已经转换成Integer类型的数值了,在业务方法中的参数却是Integer类型的名称进行接收即可。因此这些工作都是由HandlerAdapter(处理器适配器)已经进行内部处理的结果。
传统类型:http://localhost:8084/springmvc_0609/hello/index?name=1&id=10
REST形式(直接在url中写参数值,多个参数值之间用 / 隔开,并且要在注解@RequestMapping(value = “/rest/{name}/{id}”)中以添加参数名称,以{}中书写,多个参数名称用 / 隔开:http://localhost:8084/springmvc_0609/hello/rest/zhangsan/10
@RequestMapping(value = "/rest/{name}/{id}",method = RequestMethod.GET)
public String rest(@PathVariable(value = "name") String name,@PathVariable(value = "id") int id){
System.out.println("name1 = " + name);
System.out.println("id1 = " + id);
return "index";
}
上述代码中,当业务方法中的形参名称进行对URL下的参数值接收,那么就必须添加@PathVariable注解来指定映射到业务方法中的参数名称(这个最主要的是这个注解的value属性值要与@RequestMapping注解中的value中的指定对应的参数名称对应,其实@PathVariable中的value属性值可不与业务方法中的参数名称相同),则是@PathVariable注解完成请求参数与业务方法中的形参进行映射。
SpringMVC通过映射可以直接在业务方法中获取到Cookie的值。
@RequestMapping(value = "/cookie")
public String cookie(@CookieValue(value = "JSESSIONID") String jsession){
System.out.println("jsession = " + jsession);
return "index";
}
SpringMVC会根据请求参数名和JavaBean属性名进行自动匹配,自动为对象属性填充值,同时支持级联属性(也就是实体对象中包含另外一个实体对象)
实体类代码
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private Address address;
}
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {
private String addressName;
}
前端jsp注册表单页面
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/13
Time: 22:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/hello/save" method="post">
用户ID:<input type="text" name="id"><br>
用户名:<input type="text" name="name"><br>
地址名:<input type="text" name="address.addressName"><br>
<input type="submit" value="注册">
form>
body>
html>
控制器Handler代码
package com.wuzhou.controller;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping(value = "/hello")
public class Handler {
@RequestMapping(value = "/save",method = RequestMethod.POST)
public String save(User user){
System.out.println("user = " + user);
return "index";
}
}
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
SpringMVC是以默认是页面转发分形式响应jsp
(1)页面转发控制器
@RequestMapping(value = "/forward")
public String forward(){
System.out.println("forward页面转发");
return "forward:/index.jsp";
}
(2)页面重定向控制器
@RequestMapping(value = "/redirect")
public String redirect(){
System.out.println("redirect页面重定向");
return "redirect:/index.jsp";
}
数据绑定:在后端的业务方法中直接获取前端HTTP请求中的参数,将请求中的参数映射中业务方法中的形参中。
SpringMVC 中数据绑定的工作交给HandlerAdapter来完成的。
@RequestMapping(value = "/basicType",produces = "application/json;charset=utf-8")//其中的produce属性值是返回含有中文的字符不会在浏览器上出现乱码或者解析不出来
@ResponseBody
public String basicType(int id){
return "id的值为:"+id;
}
上述代码中的@ResponseBody注解是表示SpringMVC会直接将业务方法中的返回值响应给客户端,如果不加这个@ResponseBody注解的话,SpringMVC会将业务方法的返回值传递给DispatcherServlet去处理,然后再由DispatcherServlet去调用ViewResolver对返回值进行解析,映射到一个jsp资源。
@RequestMapping(value = "/packageType",produces = "application/json;charset=utf-8")
@ResponseBody
public String packageType(Integer id){
return "id的值为:"+id;
}
@RequestMapping(value = "/packageType",produces = "application/json;charset=utf-8")
@ResponseBody
public String packageType(@RequestParam(value = "num",required = false,defaultValue = "0") Integer id){
return "id的值为:"+id;
}
包装类可以接收null值,当http请求参数中为null值时,使用包装类定义形参的数据类型,程序不会抛出异常;如果是基本数据类型的话,http请求参数中中的值为空的话,就会抛出空指针异常。
@RequestParam注解:
数组类型参数输入
@RestController
//相当于@Controller和@ResponseBody结合
@RequestMapping(value = "/data")
public class DataHandler {
@RequestMapping(value = "/array",produces = "application/json;charset=utf-8")
//@ResponseBody
public String array(String [] name){
String s = Arrays.toString(name);
System.out.println("s = " + s);
return s;
}
}
等同于
@Controller
//相当于@Controller和@ResponseBody结合
@RequestMapping(value = "/data")
public class DataHandler {
@RequestMapping(value = "/array",produces = "application/json;charset=utf-8")
@ResponseBody
public String array(String [] name){
String s = Arrays.toString(name);
System.out.println("s = " + s);
return s;
}
}
上述代码中的@RestController注解,表示直接将业务方法中的返回值响应给客户端,不进行视图解析;然而@Contoller表示该控制器的每一个业务方法的返回值都会交给视图解析器进行解析,如果只是想把业务方法中的返回值响应给客户端,则不需要进行视图解析,只需要在对应的方法上添加@ResponseBody即可。
业务类
@RestController
//相当于@Controller和@ResponseBody结合
@RequestMapping(value = "/data")
public class DataHandler {
@RequestMapping(value = "/save",produces ="application/json;charset=utf-8" )
public String save(User user){
//第一种方式
// StringBuffer str=new StringBuffer();
// StringBuffer append = str.append(user);
// System.out.println(append);
// return str.toString();
//第二种方式
String str="";
str+=user;
System.out.println("user = " + str);
return str;
}
}
实体封装类
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private Address address;
}
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {
private String addressName;
}
jsp前端
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/13
Time: 22:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/hello/save" method="post">
用户ID:<input type="text" name="id"><br>
用户名:<input type="text" name="name"><br>
地址名:<input type="text" name="address.addressName"><br>
<input type="submit" value="注册">
form>
body>
html>
业务类
@RestController
//相当于@Controller和@ResponseBody结合
@RequestMapping(value = "/data")
public class DataHandler {
// @RequestMapping(value = "/list",produces ="application/json;charset=utf-8")
@RequestMapping(value = "/list")
public String list(UserList users){
StringBuffer s=new StringBuffer();
for (User user:users.getUsers()) {
s.append(user);
}
return s.toString();
}
}
集合封装类
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserList {
private List<User> users;
}
jsp前端
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/13
Time: 22:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/data/list" method="post">
用户1ID:<input type="text" name="users[0].id"><br>
用户1名:<input type="text" name="users[0].name"><br>
<%-- 地址名:<input type="text" name="address.addressName"><br>--%>
用户2ID:<input type="text" name="users[1].id"><br>
用户2名:<input type="text" name="users[1].name"><br>
用户3ID:<input type="text" name="users[2].id"><br>
用户3名:<input type="text" name="users[2].name"><br>
<input type="submit" value="注册">
form>
body>
html>
处理@ResponseBody注解的中文乱码问题
(1)在springmvc.xml文件中配置消息转换器进行处理
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.wuzhou"/>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=utf-8"/>
bean>
mvc:message-converters>
mvc:annotation-driven>
beans>
(2)就是在@ResquestMapping注解中的produces注解属性中添加格式为produces ="application/json;charset=utf-8"就能处理返回给客户端含有中文字符的乱码问题
自定义封装类
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserMap {
private Map<String,User> userMaps;
}
业务方法
@RestController
//相当于@Controller和@ResponseBody结合
@RequestMapping(value = "/data")
public class DataHandler {
@RequestMapping(value = "/getMap",produces ="application/json;charset=utf-8")
public String map(UserMap map) {
StringBuffer s=new StringBuffer();
for (String key:map.getUserMaps().keySet()) {
User user = map.getUserMaps().get(key);
s.append(user);
}
return s.toString();
}
}
相当于
@RestController
//相当于@Controller和@ResponseBody结合
@RequestMapping(value = "/data")
public class DataHandler {
@RequestMapping(value = "/map",produces ="application/json;charset=utf-8")
public Map<String,User> getMap(UserMap map) {
Map<String,User> map1=new HashMap<>();
Map<String, User> userMaps = map.getUserMaps();
userMaps.entrySet().stream().forEach(stringUserEntry -> {
System.out.println("stringUserEntry = " + stringUserEntry);
map1.put(stringUserEntry.getKey(),stringUserEntry.getValue());
});
return map1;
}
}
相当于
@RestController
//相当于@Controller和@ResponseBody结合
@RequestMapping(value = "/data")
public class DataHandler {
@RequestMapping(value = "/map",produces ="application/json;charset=utf-8")
public List<User> getMap(UserMap map) {
List<User> userList=new ArrayList<>();
Map<String, User> userMaps = map.getUserMaps();
userMaps.entrySet().stream().forEach(stringUserEntry -> {
System.out.println("stringUserEntry = " + stringUserEntry);
userList.add(stringUserEntry.getValue());
});
return userList;
}
}
jsp前端
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/13
Time: 22:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/data/map" method="post">
用户1ID:<input type="text" name="userMaps['a'].id"><br>
用户1名:<input type="text" name="userMaps['a'].name"><br>
<%-- 地址名:<input type="text" name="address.addressName"><br>--%>
用户2ID:<input type="text" name="userMaps['b'].id"><br>
用户2名:<input type="text" name="userMaps['b'].name"><br>
用户3ID:<input type="text" name="userMaps['c'].id"><br>
用户3名:<input type="text" name="userMaps['c'].name"><br>
<input type="submit" value="注册">
form>
body>
html>
(一)处理SpringMVC中无法加载静态资源两种形式
在web.xml文件中添加配置即可
(1)
<servlet-mapping>
<servlet-name>defaultservlet-name>
<url-pattern>*.jsurl-pattern>
servlet-mapping>
在springmvc.xml文件中添加配置即可
(2)
<mvc:default-servlet-handler/>
(二)jsp异步请求代码
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/17
Time: 11:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
<script type="text/javascript" src="js/jquery-3.6.0.js">script>
<script type="text/javascript">
$(function () {
var user={
"id":1,
"name":"张三",
"address":{
"addressName":"人民路"
}
};
$.ajax({
url:"/data/json",
/*发送请求的地址*/
data:JSON.stringify(user),
/*要求为Object或String类型的参数,发送到服务器的数据。
对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}
转换为&foo1=bar1&foo2=bar2。*/
type:"POST",
/*要求为String类型的参数,请求方式(post或get)默认为get。*/
contentType:"application/json;charset=utf-8",
/*发送信息至服务器的内容格式编码,可能有中文参数*/
dataType:"JSON",
/*要求为String类型的参数,预期服务器返回的数据类型----返回json格式数据*/
success:function (data) {
/*要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。*/
alert(data.id+"===="+data.name+"======"+data.address.addressName);
}
});
});
script>
head>
<body>
body>
html>
业务方法
@RestController
//相当于@Controller和@ResponseBody结合
@RequestMapping(value = "/data")
public class DataHandler {
@RequestMapping(value = "/json",produces ="application/json;charset=utf-8")
public User json(@RequestBody User user){
System.out.println("user = " + user);
user.setId(6);
user.setName("王五");
return user;
}
}
springmvc中的JSON和javabean的转换需要借助于fastjson,pom.xml文件中需要添加相关依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.72version>
dependency>
还需要在spring.xml文件中添加和配置fastjson的配置
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=utf-8"/>
bean>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"/>
mvc:message-converters>
mvc:annotation-driven>
(1)jsp四大作用域对应的内置对象:pageContext、request、session、application。
(2)模型数据的绑定是由ViewResolver来完成的,但在实际开发中,我们需要先添加模型数据,再交给ViewResolver来绑定。
(3)springMVC提供了以下几种方式添加模型数据
(Map、Model、ModeAndView属于request对象)、@SessionAttribute属于session对象、@ModelAttribute属于request对象
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@Controller
@RequestMapping(value = "/view")
public class DataViewController {
@RequestMapping(value = "/map")
public String map(Map<String,Object> map){
User user=new User();
user.setId(1);
user.setName("张三");
user.setAddress(new Address("人民路"));
map.put("user",user);
return "view";
}
}
(2)jsp前端
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/19
Time: 21:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%--用来解析el表达式从后端传来的数据--%>
<html>
<head>
<title>Titletitle>
<%-- <script type="text/javascript" src="js/jquery-3.6.0.js">script>--%>
<%-- <script type="text/javascript">script>--%>
head>
<body>
${requestScope.user}
body>
html>
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@Controller
@RequestMapping(value = "/view")
public class DataViewController {
@RequestMapping(value = "/model")
public String model(Model model){
User user=new User();
user.setId(2);
user.setName("张三2");
user.setAddress(new Address("人民路2"));
model.addAttribute("user",user);
return "view";
}
}
(2)jsp前端
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/19
Time: 21:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%--用来解析el表达式从后端传来的数据--%>
<html>
<head>
<title>Titletitle>
<%-- <script type="text/javascript" src="js/jquery-3.6.0.js">script>--%>
<%-- <script type="text/javascript">script>--%>
head>
<body>
${requestScope.user}
body>
html>
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.InternalResourceView;
import java.util.Map;
@Controller
@RequestMapping(value = "/view")
public class DataViewController {
@RequestMapping(value = "/modelandView")
public ModelAndView modelAndView(ModelAndView modelAndView){
User user=new User();
user.setId(3);
user.setName("张三3");
user.setAddress(new Address("人民路3"));
modelAndView.addObject("user",user);
modelAndView.setViewName("view");
return modelAndView;
}
@RequestMapping(value = "/modelandView1")
public ModelAndView modelAndView1(){
User user=new User();
user.setId(3);
user.setName("张三3");
user.setAddress(new Address("人民路3"));
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("user",user);
modelAndView.setViewName("view");
return modelAndView;
}
@RequestMapping(value = "/modelandView2")
public ModelAndView modelAndView2(){
User user=new User();
user.setId(4);
user.setName("张三4");
user.setAddress(new Address("人民路4"));
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("user",user);
View view=new InternalResourceView("/view.jsp");
modelAndView.setView(view);
return modelAndView;
}
@RequestMapping(value = "/modelandView3")
public ModelAndView modelAndView3(){
User user=new User();
user.setId(5);
user.setName("张三5");
user.setAddress(new Address("人民路5"));
ModelAndView modelAndView=new ModelAndView("view");
modelAndView.addObject("user",user);
return modelAndView;
}
@RequestMapping(value = "/modelandView4")
public ModelAndView modelAndView4(){
User user=new User();
user.setId(6);
user.setName("张三6");
user.setAddress(new Address("人民路6"));
View view=new InternalResourceView("/view.jsp");
ModelAndView modelAndView=new ModelAndView(view);
modelAndView.addObject("user",user);
return modelAndView;
}
@RequestMapping(value = "/modelandView5")
public ModelAndView modelAndView5(Map<String,User> map){
User user=new User();
user.setId(7);
user.setName("张三7");
user.setAddress(new Address("人民路7"));
map.put("user",user);
ModelAndView modelAndView=new ModelAndView("view",map);
return modelAndView;
}
@RequestMapping(value = "/modelandView6")
public ModelAndView modelAndView6(Map<String,User> map){
User user=new User();
user.setId(8);
user.setName("张三8");
user.setAddress(new Address("人民路8"));
map.put("user",user);
View view=new InternalResourceView("/view.jsp");
ModelAndView modelAndView=new ModelAndView(view,map);
return modelAndView;
}
@RequestMapping(value = "/modelandView7")
public ModelAndView modelAndView7(){
User user=new User();
user.setId(9);
user.setName("张三9");
user.setAddress(new Address("人民路9"));
ModelAndView modelAndView=new ModelAndView("view","user",user);
return modelAndView;
}
@RequestMapping(value = "/modelandView8")
public ModelAndView modelAndView8(){
User user=new User();
user.setId(10);
user.setName("张三10");
user.setAddress(new Address("人民路10"));
View view=new InternalResourceView("/view.jsp");
ModelAndView modelAndView=new ModelAndView(view,"user",user);
return modelAndView;
}
}
@Controller
@RequestMapping(value = "/view")
public class DataViewController {
@RequestMapping(value = "request")
public String request(HttpServletRequest request){
User user=new User();
user.setId(11);
user.setName("张三11");
user.setAddress(new Address("人民路11"));
request.setAttribute("user",user);
return "view";
}
}
(2)jsp前端
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/19
Time: 21:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%--用来解析el表达式从后端传来的数据--%>
<html>
<head>
<title>Titletitle>
<%-- <script type="text/javascript" src="js/jquery-3.6.0.js">script>--%>
<%-- <script type="text/javascript">script>--%>
head>
<body>
${requestScope.user}
body>
html>
@ModelAttribute
public User getUser(){
User user=new User();
user.setId(12);
user.setName("张三12");
user.setAddress(new Address("人民路12"));
return user;
}
等同于
@ModelAttribute
public void getUser(Map<String,User> map){
User user=new User();
user.setId(12);
user.setName("张三12");
user.setAddress(new Address("人民路12"));
map.put("user",user);
}
等同于
@ModelAttribute
public void getUser(Model model) {
User user = new User();
user.setId(13);
user.setName("张三13");
user.setAddress(new Address("人民路13"));
model.addAttribute("user",user);
}
(2)业务方法中无需再处理模型数据,只需要返回视图即可
@Controller
@RequestMapping(value = "/view")
public class DataViewController {
@RequestMapping(value = "/modelAttribute")
public String modelAttribute(){
return "view";
}
}
@Controller
@RequestMapping(value = "/view")
public class DataViewController {
@RequestMapping(value = "/session")
public String session(HttpServletRequest request){
HttpSession session = request.getSession();
User user = new User();
user.setId(14);
user.setName("张三14");
user.setAddress(new Address("人民路14"));
session.setAttribute("user",user);
return "view";
}
}
等同于
@Controller
@RequestMapping(value = "/view")
public class DataViewController {
@RequestMapping(value = "/session1")
public String session1(HttpSession session){
User user = new User();
user.setId(15);
user.setName("张三15");
user.setAddress(new Address("人民路15"));
session.setAttribute("user",user);
return "view";
}
}
(1)对于在DataViewController控制器中的所有业务方法,只要向request中添加key=“user”、key="address"的对象时,springMVC会自动将数据添加到session中,并保持key不变。
@Controller
@RequestMapping(value = "/view")
//@SessionAttributes("user")//该注解里面的value值是指对应相对应的键的值,同时也支持添加多个
@SessionAttributes(value = {"user","address"})
public class DataViewController {
}
(2)对于在DataViewController控制器中的所有业务方法,只要向request中添加type=User.class、type=Address.class的对象时,springMVC会自动将数据添加到session中,并保持key不变。
@Controller
@RequestMapping(value = "/view")
@SessionAttributes(types = {User.class,Address.class})
public class DataViewController {
}
@Controller
@RequestMapping(value = "/view")
//@SessionAttributes("user")//该注解里面的value值是指对应相对应的键的值,同时也支持添加多个
//@SessionAttributes(value = {"user","address"})
//@SessionAttributes(types = {User.class,Address.class})
//@SessionAttributes(types = User.class)//这个是通过数据类型去添加的,也支持多个数据类型对象
/**
* 上面两个注解的SessionAttribute是全局的,
* 绝大多数业务方法都不需要既是把模型数据放入session对象中,
* 更多的是把它放在request对象中,更多的是不支持使用的
*/
public class DataViewController {
@RequestMapping(value = "/application")
public String application(HttpServletRequest request){
User user = new User();
user.setId(16);
user.setName("张三16");
user.setAddress(new Address("人民路16"));
ServletContext context = request.getServletContext();
context.setAttribute("user",user);
return "view";
}
}
数据转换器是指将客户端http请求中的参数转换为业务方法中定义的形参,其自定义表示开发者可以自主设计转换器的方式,HandlerAdapter已经提供了通用的转换器,譬如String类型转int类型、String类型转double类型以及表单数据进行自动封装等。但是在特定的业务场景之下,HandlerAdapter无法进行数据转换,需要开发者自己定义转换器。
(1)客户端输入String类型的数据"2021-06-11",自定义转换器将该数据转换为Date类型的对象
package com.wuzhou.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Controller;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 自定义日期转换器
*/
//@Controller
public class DateConverter implements Converter<String, Date> {//Converter加泛型指定待传入转换的参数类型和转换之后返回的参数类型
private String pattern;
public DateConverter(String pattern){
this.pattern=pattern;
}
@Override
public Date convert(String s) {
SimpleDateFormat simpleDateFormat=new SimpleDateFormat(this.pattern);
Date date=null;
try {
date = simpleDateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.wuzhou"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.wuzhou.converter.DateConverter">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
bean>
list>
property>
bean>
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=utf-8"/>
bean>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"/>
mvc:message-converters>
mvc:annotation-driven>
beans>
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/21
Time: 12:50
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/converter/date" method="post">
请输入日期:<input type="text" name="date"/>(yyyy-MM-dd格式)<br/>
<input type="submit" value="提交">
form>
body>
html>
package com.wuzhou.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping(value = "/converter")
public class DateConverter {
@RequestMapping(value = "/date")
public String date(Date date){
return date.toString();
}
}
(2)客户端输入String类型的数据"1-张三-20",自定义转换器将该数据转换为Student类型的对象
package com.wuzhou.converter;
import com.wuzhou.entity.Student;
import org.springframework.core.convert.converter.Converter;
public class StudentConverter implements Converter<String, Student> {
@Override
public Student convert(String s) {
//1-张三-20转成{"1","张三","20"}
String[] split = s.split("-");
Student student=new Student();
student.setId(Integer.parseInt(split[0]));
student.setName(split[1]);
student.setAge(Integer.parseInt(split[2]));
return student;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.wuzhou"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.wuzhou.converter.DateConverter">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
bean>
<bean class="com.wuzhou.converter.StudentConverter"/>
list>
property>
bean>
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=utf-8"/>
bean>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"/>
mvc:message-converters>
mvc:annotation-driven>
beans>
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/21
Time: 16:13
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/converter/student" method="post">
请输入学生信息:<input type="text" name="student"/>(id-name-age)<br/>
<input type="submit" name="提交"/>
form>
body>
html>
package com.wuzhou.controller;
import com.wuzhou.entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping(value = "/converter")
public class DateConverter {
@RequestMapping(value = "/student")
public String student(Student student){
return student.toString();
}
}
REST:Representational State Tranfer,资源表现层状态转换,是目前比较主流的一种互联网软件架构,它结构清晰、标准规范、易于理解、便于扩展。
(1)REST具体的操作就是http协议中的四个表示操作方式的动词分别对应CRUD的基本操作。
package com.wuzhou.controller;
import com.wuzhou.entity.Student;
import com.wuzhou.mapper.StudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
@RestController
@RequestMapping(value = "/rest")
public class RestHandler {
@Autowired
private StudentMapper studentMapper;
// @RequestMapping(value = "/findAll")
// public Collection findAll(HttpServletResponse response){
// response.setContentType("text/json;charset=utf-8");
// //处理数据的中文乱码响应给前端中文数据出现的问题,这个相当于是同步的请求,需要进行响应编码处理
// return studentMapper.findAll();
// }
@GetMapping(value = "/findAll", produces = "application/json;charset=utf-8")
public Collection<Student> findAll(HttpServletResponse response) {
//response.setContentType("text/json;charset=utf-8");
//处理数据的中文乱码响应给前端中文数据出现的问题,这个相当于是同步的请求,需要进行响应编码处理
return studentMapper.findAll();
}
@PostMapping(value = "/findById/{id1}")
public Student findById(@PathVariable("id1") long id1) {
return studentMapper.findById(id1);
}
// @GetMapping(value = "/findById")
// public Student findById(long id1) {
// return studentMapper.findById(id1);
//
// }
// @PostMapping(value = "/save")
// public void save(Student student){
// studentMapper.saveOrUpdate(student);
// }
// @PostMapping(value = "/save", produces = "application/json;charset=utf-8")
// public void save(@RequestBody Student student) {
// studentMapper.saveOrUpdate(student);
// }
@PostMapping(value = "/save", produces = "application/json;charset=utf-8")
public void save(@RequestBody Student student) {
studentMapper.saveOrUpdate(student);
}
// @PutMapping(value = "/update")
// public void update(@RequestBody Student student) {
// studentMapper.saveOrUpdate(student);
// }
@PutMapping(value = "/update",produces = "application/json;charset=utf-8")
public void update(@RequestBody Student student) {
studentMapper.saveOrUpdate(student);
}
@DeleteMapping(value = "/deleteById/{id2}")
public void deleteById(@PathVariable("id2") long id2) {
studentMapper.deleteById(id2);
}
}
package com.wuzhou.mapper;
import com.wuzhou.entity.Student;
import java.util.Collection;
public interface StudentMapper {
public Collection<Student> findAll();
//查询所有数据
public Student findById(long id);
//根据id查询
public void saveOrUpdate(Student student);
//新增或者更新操作
public void deleteById(long id);
//根据ID删除操作
}
package com.wuzhou.mapper.Impl;
import com.wuzhou.entity.Student;
import com.wuzhou.mapper.StudentMapper;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Repository
public class StudentMapperImpl implements StudentMapper {
private static Map<Long,Student> studentMap;
static {
studentMap=new HashMap<>();
studentMap.put(1L,new Student(1L,"李白",2));
studentMap.put(2L,new Student(2L,"杜甫",21));
studentMap.put(3L,new Student(3L,"王昌龄",22));
}
@Override
public Collection<Student> findAll() {
return studentMap.values();
}
@Override
public Student findById(long id) {
return studentMap.get(id);
}
@Override
public void saveOrUpdate(Student student) {
studentMap.put(student.getId(), student);
}
@Override
public void deleteById(long id) {
studentMap.remove(id);
}
}
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Long id;
private String name;
private Integer age;
}
它的底层是使用的是Apache fileupload组件完成上传的,SpringMVC对这种方式已经进行了封装。
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.6version>
dependency>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.4version>
dependency>
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/1
Time: 13:46
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false"%>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="img"/>
<%--这里的name属性值file是要与前端控制器的MultipartFile file中的对象file名称一样
才能获取传过来的对象进行封装,并且获取对象file的参数:
file =
MultipartFile[field="file",
filename=WPS图片-修改尺寸(1).jpg,
contentType=image/jpeg,
size=16561]
--%>
<input type="submit" value="上传"/>
<br>
<img src="${path}">
form>
body>
html>
以上前端代码需要注意几点:
(1)input中的type属性是要是file文件
(2)form的method设置为post(get请求只能将文件名上传给服务器)
(3)form中的enctype属性要设置为multipart/form-data(如果不设置只能将文件名上传给服务器)
package com.wuzhou.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping(value = "/file")
public class FileHandler {
@RequestMapping(value = "/upload")
public String upload(MultipartFile img, HttpServletRequest request) {
// System.out.println("file = " + file);
if (img.getSize() > 0) {
//获取保存上传文件的file的路径
String path = request.getServletContext().getRealPath("file");
//获取上传文件名
String filename = img.getOriginalFilename();
File file = new File(path, filename);
try {
img.transferTo(file);
//保存上传之后的文件路径
request.setAttribute("path", "/file/" + filename);
} catch (IOException e) {
e.printStackTrace();
}
}
return "uploadFile";
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
beans>
<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 Applicationdisplay-name>
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>defaultservlet-name>
<url-pattern>*.jsurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>defaultservlet-name>
<url-pattern>*.jpgurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>defaultservlet-name>
<url-pattern>*.pngurl-pattern>
servlet-mapping>
web-app>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.6version>
dependency>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.4version>
dependency>
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/1
Time: 13:46
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="/file/uploads" method="post" enctype="multipart/form-data">
文件1:<input type="file" name="imgs"/><br>
文件2:<input type="file" name="imgs"/><br>
文件3:<input type="file" name="imgs"/><br>
文件4:<input type="file" name="imgs"/><br>
<%--这里的name属性值file是要与前端控制器的MultipartFile file中的对象file名称一样
才能获取传过来的对象进行封装,并且获取对象file的参数:
file =
MultipartFile[field="file",
filename=WPS图片-修改尺寸(1).jpg,
contentType=image/jpeg,
size=16561]
--%>
<input type="submit" value="上传"/>
<br>
<%--需要利用jsp标签库中的foreach循环标签--%>
<c:forEach items="${files}" var="file">
<img src="${file}" width="300px">
c:forEach>
form>
body>
html>
package com.wuzhou.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping(value = "/file")
public class FileHandler {
//@RequestMapping(value = "/uploads")
@PostMapping(value = "/uploads")
public String uploads(MultipartFile[] imgs, HttpServletRequest request) {
// System.out.println("file = " + file);
List<String> files = new ArrayList<>();
for (MultipartFile img : imgs) {
if (img.getSize() > 0) {
//获取保存上传文件的file的路径
String path = request.getServletContext().getRealPath("file");
//获取上传文件名
String filename = img.getOriginalFilename();
File file = new File(path, filename);
try {
img.transferTo(file);
//保存上传之后的文件路径
//request.setAttribute("path", "/file/" + filename);
files.add("/file/" + filename);
} catch (IOException e) {
e.printStackTrace();
}
}
}
request.setAttribute("files", files);
return "uploadFiles";
}
}
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.6version>
dependency>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.4version>
dependency>
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/1
Time: 23:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<a href="/file/download/1">1.jpga>
<a href="/file/download/2">2.jpga>
body>
html>
package com.wuzhou.controller;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping(value = "/file")
public class FileHandler {
@GetMapping(value = "/download/{name}")
public void download(@PathVariable("name") String name, HttpServletRequest request, HttpServletResponse response) {
if (name != null) {
name+=".jpg";
String path = request.getServletContext().getRealPath("file");
File file = new File(path, name);
OutputStream ops = null;
if (file.exists()) {
response.setContentType("application/forc-download");
// response.setHeader("Content-Disposition", "attachment;filename=" + name);
try {
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(),"utf-8"));
//这个是面对下载文件中含有中文名字的下载文件名出现乱码问题得到很好的解决
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
ops = response.getOutputStream();
ops.write(FileUtils.readFileToByteArray(file));
ops.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ops != null) {
try {
ops.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
package com.wuzhou.controller;
import com.wuzhou.entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value = "/tag")
public class TagHandler {
@RequestMapping(value = "/getTag")
public ModelAndView getTag(){
ModelAndView modelAndView=new ModelAndView("show");
//ModelAndView modelAndView=new ModelAndView("tagShow");
Student student=new Student(1L,"王五",28);
modelAndView.addObject("student",student);
return modelAndView;
}
}
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/3
Time: 10:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>学生信息title>
head>
<body>
<form>
学生ID是:<input type="text" name="id" value="${student.id}"><br>
学生姓名是:<input type="text" name="name" value="${student.name}"><br>
学生年龄是:<input type="text" name="age" value="${student.age}"><br>
<input type="submit" value="提交"/>
form>
body>
html>
package com.wuzhou.controller;
import com.wuzhou.entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value = "/tag")
public class TagHandler {
@RequestMapping(value = "/getTag")
public ModelAndView getTag(){
//ModelAndView modelAndView=new ModelAndView("show");
ModelAndView modelAndView=new ModelAndView("tagShow");
Student student=new Student(1L,"王五",28);
modelAndView.addObject("student",student);
return modelAndView;
}
}
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/3
Time: 10:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>学生信息title>
head>
<body>
<form:form modelAttribute="student">
<%--这里的modelAttribute中的属性是与后台的控制器的模型视图绑定的别名要一样--->modelAndView.addObject("student",student);--%>
学生ID:<form:input path="id"/><br>
学生姓名:<form:input path="name"/><br>
学生年龄:<form:input path="age"/><br>
<input type="submit" value="提交"/>
form:form>
body>
html>
(1)jsp页面导入SpringMVC表单标签库,与导入JSTL(javaserver pages tag language)标签库的语法非常相似,前缀通常prefix是可以自定义的,通常定义为form。
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
(2)将form表单与模型数据进行绑定,通过modelAttribute属性完成绑定,将modelAttribute属性设置的值为模型数据对应的key值。
后天Handler代码:modelAndView.addObject("student",student);
jsp代码:<form:form modelAttribute="student">
(3)form表单完成绑定之后,将模型数据中的值取出绑定到不同的前台标签中,通过设置标签的path属性完成,将path属性设置为模型数据对应的属性名即可。
学生ID:<form:input path="id"/><br>
学生姓名:<form:input path="name"/><br>
学生年龄:<form:input path="age"/><br>
<form:form modelAttribute="student">
</form:form>
学生ID:<form:input path="id"/><br>
这个标签渲染的是HTML中的input标签中的type="text"属性,form标签绑定的是模型数据,input标签中绑定的是模型数据中的属性值,通过path属性可以与模型数据中的属性名进行一一对应,并且支持级联操作(所谓的级联就是对象中含有对象作为属性)。
学生地址:<form:input path="address.addressName"/><br>
学生密码:<form:password path="password"/><br>
这个标签是HTML中的input标签中的type="password"属性,通过path属性与模型数据的属性进行绑定,password标签的值不会在页面中显示。
复选框:<form:checkbox path="flag"/>flag的值<br>
这个渲染的是HTML中的input标签的type="checkbox"属性,通过path属性与模型数据的属性值进行绑定,其值可以绑定boolean、数组以及集合数据类型的数据。
如果绑定的是Boolean类型的值,如果该变量的值为true,则表示选中该复选框中的值,否则表示不选中。
如果绑定数组或者集合,数组或者集合中的元素等于checkbox中的value值,表示选中,否则表示不选中。
(1)jsp代码
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/3
Time: 10:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%--引入springmvc标签库--%>
<html>
<head>
<title>学生信息</title>
</head>
<body>
<%--<form:form modelAttribute="user">--%>
<form:form modelAttribute="student">
<%--这里的modelAttribute中的属性是与后台的控制器的模型视图绑定的别名要一样--->modelAndView.addObject("student",student);--%>
爱好:<form:checkbox path="hobby" value="读书"/>读书<br>
<form:checkbox path="hobby" value="看报"/>看报<br>
<form:checkbox path="hobby" value="喝酒"/>喝酒<br>
<form:checkbox path="hobby" value="旅游"/>旅游<br>
<form:checkbox path="hobby" value="打羽毛球"/>打羽毛球<br>
<form:checkbox path="hobby" value="打篮球"/>打篮球<br>
<form:checkbox path="hobby" value="打乒乓球"/>打乒乓球<br>
<form:checkbox path="hobby" value="打牌"/>打牌<br>
<input type="submit" value="提交"/>
</form:form>
</body>
</html>
(2)Handler代码
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.Student;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
@Controller
@RequestMapping(value = "/tag")
public class TagHandler {
@RequestMapping(value = "/getTag")
public ModelAndView getTag(){
// ModelAndView modelAndView=new ModelAndView("show");
ModelAndView modelAndView=new ModelAndView("tagShow");
//Student student=new Student(1L,"王五",28);
// Address address=new Address("人民路");
// User user=new User(1,"张三",address);
// modelAndView.addObject("user",user);
Student student=new Student();
//student.setHobby(new String[]{"读书", "打篮球", "打乒乓球"});
student.setHobby(Arrays.asList("打羽毛球","打牌","喝酒"));
modelAndView.addObject("student",student);
return modelAndView;
}
}
(3)Student实体类
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Long id;
private String name;
private Integer age;
// private String[] hobby;
private boolean flag;
private List<String> hobby;
public Student(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
爱好:<form:checkboxes path="selectHobby" items="${student.hobby}"/><br>
这是一个渲染的是一组input标签中的type="checkbox"属性,是对form标签中的form:checkbox的一种简化,需要结合items和path属性来使用,item是表示绑定所有被遍历的集合或者数组,path是绑定被选中的集合或者数组,也可以这样理解的是,items是全部可选的集合或者数组,而path是为默认选中的集合或者数组。
(1)后端Handler处理器
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.Student;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
@Controller
@RequestMapping(value = "/tag")
public class TagHandler {
@RequestMapping(value = "/getTag")
public ModelAndView getTag(){
// ModelAndView modelAndView=new ModelAndView("show");
ModelAndView modelAndView=new ModelAndView("tagShow");
//Student student=new Student(1L,"王五",28);
// Address address=new Address("人民路");
// User user=new User(1,"张三",address);
// modelAndView.addObject("user",user);
Student student=new Student();
//student.setHobby(new String[]{"读书", "打篮球", "打乒乓球"});
student.setHobby(Arrays.asList("打羽毛球","打牌","喝酒","旅游"));
student.setSelectHobby(Arrays.asList("打牌","打羽毛球","旅游"));
modelAndView.addObject("student",student);
return modelAndView;
}
}
(2)实体类
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Long id;
private String name;
private Integer age;
// private String[] hobby;
private boolean flag;
private List<String> hobby;
private List<String> selectHobby;
public Student(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
(3)前端jsp代码
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/3
Time: 10:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%--引入springmvc标签库--%>
<html>
<head>
<title>学生信息</title>
</head>
<body>
<%--<form:form modelAttribute="user">--%>
<form:form modelAttribute="student">
<%--这里的modelAttribute中的属性是与后台的控制器的模型视图绑定的别名要一样--->modelAndView.addObject("student",student);--%>
爱好:<form:checkboxes path="selectHobby" items="${student.hobby}"/><br>
<input type="submit" value="提交"/>
</form:form>
</body>
</html>
上述代码需要注意的是path可以直接绑定模型数据的属性值,items则需要通过EL表达式的形式从域中获取数据,不能直接写属性名。
单选框:<form:radiobutton path="radioId" value="1"/>单选框<br>
渲染的是HTML中的一个input的type属性type=“radio”,绑定的数据与标签的value值相等则为选中,否则不选中。
(1)前端jsp代码
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/3
Time: 10:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%--引入springmvc标签库--%>
<html>
<head>
<title>学生信息</title>
</head>
<body>
<%--<form:form modelAttribute="user">--%>
<form:form modelAttribute="student">
<%--这里的modelAttribute中的属性是与后台的控制器的模型视图绑定的别名要一样--->modelAndView.addObject("student",student);--%>
单选框:<form:radiobutton path="radioId" value="1"/>单选框<br>
<input type="submit" value="提交"/>
</form:form>
</body>
</html>
(2)实体类代码
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Long id;
private String name;
private Integer age;
// private String[] hobby;
private boolean flag;
private List<String> hobby;
private List<String> selectHobby;
private Integer radioId;
public Student(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
(3)Handler代码
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.Student;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
@Controller
@RequestMapping(value = "/tag")
public class TagHandler {
@RequestMapping(value = "/getTag")
public ModelAndView getTag(){
// ModelAndView modelAndView=new ModelAndView("show");
ModelAndView modelAndView=new ModelAndView("tagShow");
//Student student=new Student(1L,"王五",28);
// Address address=new Address("人民路");
// User user=new User(1,"张三",address);
// modelAndView.addObject("user",user);
Student student=new Student();
student.setRadioId(1);
modelAndView.addObject("student",student);
return modelAndView;
}
}
<form:radiobuttons path="selectGrape" items="${student.map}"/>
这个渲染的是HTML中的一组input标签属性中的type="radio"属性值,这里需要结合items和path两个属性来使用,items是用来绑定被遍历的数组或者集合,而path绑定的是被选中的值,items是为全部可选类型,path是默认选中的选项,其用法和form:checkboxes一致
(1)前端代码
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/3
Time: 10:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%--引入springmvc标签库--%>
<html>
<head>
<title>学生信息</title>
</head>
<body>
<%--<form:form modelAttribute="user">--%>
<form:form modelAttribute="student">
<%--这里的modelAttribute中的属性是与后台的控制器的模型视图绑定的别名要一样--->modelAndView.addObject("student",student);--%>
单选框:<form:radiobutton path="radioId" value="1"/>单选框<br>
学生年级:<form:radiobuttons path="selectGrape" items="${student.map}"/><br>
<input type="submit" value="提交"/>
</form:form>
</body>
</html>
(2)实体类
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Long id;
private String name;
private Integer age;
// private String[] hobby;
private boolean flag;
private List<String> hobby;
private List<String> selectHobby;
private Integer radioId;
private Map<Integer,String> map;
private Integer selectGrape;
public Student(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
(3)Handler处理器
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.Student;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping(value = "/tag")
public class TagHandler {
@RequestMapping(value = "/getTag")
public ModelAndView getTag(){
// ModelAndView modelAndView=new ModelAndView("show");
ModelAndView modelAndView=new ModelAndView("tagShow");
//Student student=new Student(1L,"王五",28);
// Address address=new Address("人民路");
// User user=new User(1,"张三",address);
// modelAndView.addObject("user",user);
Student student=new Student();
student.setRadioId(1);
Map<Integer,String> map=new HashMap<>();
map.put(1,"一年级");
map.put(2,"二年级");
map.put(3,"三年级");
student.setMap(map);
student.setSelectGrape(2);
modelAndView.addObject("student",student);
return modelAndView;
}
}
<form:select path="selectCity" items="${student.mapCity}"/>
这个标签渲染的是HTML中的一个select标签,需要结合items和path属性进行结合使用,其中items绑定的是被遍历的数组或者集合,path绑定的是被选中的集合或者数组中的值,其用法与form标签中的chechboxes和radiobuttons一样
(1)前端jsp
所在城市:<form:select path="selectCity" items="${student.mapCity}"/>
(2)后端Handler
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.Student;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping(value = "/tag")
public class TagHandler {
@RequestMapping(value = "/getTag")
public ModelAndView getTag(){
// ModelAndView modelAndView=new ModelAndView("show");
ModelAndView modelAndView=new ModelAndView("tagShow");
//Student student=new Student(1L,"王五",28);
// Address address=new Address("人民路");
// User user=new User(1,"张三",address);
// modelAndView.addObject("user",user);
Student student=new Student();
Map<Integer,String> mapCity=new HashMap<>();
mapCity.put(1,"桂林");
mapCity.put(2,"梧州");
mapCity.put(3,"河池");
mapCity.put(4,"柳州");
student.setMapCity(mapCity);
student.setSelectCity(2);
//student.setSelectCity(4);
modelAndView.addObject("student",student);
return modelAndView;
}
}
(3)实体类代码
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Long id;
private String name;
private Integer age;
// private String[] hobby;
private boolean flag;
private List<String> hobby;
private List<String> selectHobby;
private Integer radioId;
private Map<Integer,String> map;
private Integer selectGrape;
private Map<Integer,String> mapCity;
private Integer selectCity;
private String introduce;
public Student(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
(1)前端jsp
所在城市1:<form:select path="selectCity">
<form:options items="${student.mapCity}"/>
</form:select><br>
(2)Handler后端代码
Map<Integer,String> mapCity=new HashMap<>();
mapCity.put(1,"桂林");
mapCity.put(2,"梧州");
mapCity.put(3,"河池");
mapCity.put(4,"柳州");
student.setMapCity(mapCity);
student.setSelectCity(2);
//student.setSelectCity(4);
modelAndView.addObject("student",student);
(3)实体类
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Long id;
private String name;
private Integer age;
// private String[] hobby;
private boolean flag;
private List<String> hobby;
private List<String> selectHobby;
private Integer radioId;
private Map<Integer,String> map;
private Integer selectGrape;
private Map<Integer,String> mapCity;
private Integer selectCity;
private String introduce;
public Student(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
(1)jsp代码
所在城市2:<form:select path="selectCity">
<form:option value="1">柳州</form:option>
<form:option value="2">梧州</form:option>
<form:option value="3">贺州</form:option>
</form:select><br>
(2)后端Hander
package com.wuzhou.controller;
import com.wuzhou.entity.Address;
import com.wuzhou.entity.Student;
import com.wuzhou.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping(value = "/tag")
public class TagHandler {
@RequestMapping(value = "/getTag")
public ModelAndView getTag(){
// ModelAndView modelAndView=new ModelAndView("show");
ModelAndView modelAndView=new ModelAndView("tagShow");
//Student student=new Student(1L,"王五",28);
// Address address=new Address("人民路");
// User user=new User(1,"张三",address);
// modelAndView.addObject("user",user);
Student student=new Student();
student.setSelectCity(2);
//student.setSelectCity(4);
modelAndView.addObject("student",student);
return modelAndView;
}
}
(1)jsp代码
文本信息:<form:textarea path="introduce"/><br>
(2)后端Handler
student.setIntroduce("你好,我是老板");
modelAndView.addObject("student",student);
SpringMVC提供了两种数据校验的方式
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
package com.wuzhou.validator;
import com.wuzhou.entity.Account;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
/**
* 这个类是验证器类,实现了Validator接口
*/
public class AccountValidator implements Validator {
/**
* 先执行这个方法,若返回的结果是true,才往下进行,否则不往下执行
* @param aClass
* @return
*/
@Override
public boolean supports(Class<?> aClass) {
return Account.class.equals(aClass);
}
/**
* 这个才是真正验证器的实现的方法
* @param o
* @param errors
*/
@Override
public void validate(Object o, Errors errors) {
ValidationUtils.rejectIfEmpty(errors,"name",null,"姓名不能为空");
ValidationUtils.rejectIfEmpty(errors,"password",null,"密码不能为空");
}
}
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Account {
private String name;
private String password;
}
package com.wuzhou.controller;
import com.wuzhou.entity.Account;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(value = "/validator")
public class ValidatorHandler {
@GetMapping(value = "/login")
public String login(Model model){
model.addAttribute("account",new Account());
return "login";
}
@PostMapping(value = "/login")//@Validated加这个注解会自动开启验证器功能
public String login(@Validated Account account, BindingResult bindingResult){
if (bindingResult.hasErrors()){
return "login";
}
return "index";
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.wuzhou"/>
<bean id="accountValidator" class="com.wuzhou.validator.AccountValidator"/> <mvc:annotation-driven validator="accountValidator"/>
beans>
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/7/7
Time: 22:44
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="from" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form:form modelAttribute="account" action="/validator/login" method="post">
姓名:<form:input path="name"/><from:errors path="name"/><br>
密码:<form:input path="password"/><from:errors path="password"/><br>
<input type="submit" value="提交">
</form:form>
</body>
</html>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-validatorartifactId>
<version>5.4.1.Finalversion>
dependency>
<dependency>
<groupId>javax.validationgroupId>
<artifactId>validation-apiartifactId>
<version>2.0.1.Finalversion>
dependency>
<dependency>
<groupId>org.jboss.logginggroupId>
<artifactId>jboss-loggingartifactId>
<version>3.4.1.Finalversion>
dependency>
package com.wuzhou.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
@NotEmpty(message = "用户名不能为空")
private String username;
@Size(min = 6,max = 12,message = "密码6-12位")
private String password;
@Email(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\\\.[a-zA-Z0-9-]+)*\\\\.[a-zA-Z0-9]{2,6}$",message = "请输入正确的邮箱格式")
private String email;
@Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\\\\\d{8}$",message = "请输入正确的电话")
private String phone;
}
package com.wuzhou.controller;
import com.wuzhou.entity.Account;
import com.wuzhou.entity.Person;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
@Controller
@RequestMapping(value = "/validator")
public class ValidatorHandler {
@GetMapping(value = "/register")
public String register(Model model){
model.addAttribute("person",new Person());
return "register2";
}
@PostMapping(value = "/register")//@Valid加这个注解会自动开启Annotation JSR-303验证器功能
public String register(@Valid Person person, BindingResult bindingResult){
if (bindingResult.hasErrors()){
return "register2";
}
return "index";
}
}
<mvc:annotation-driven/>
<%--
Created by IntelliJ IDEA.
User: laowangzhuamyong
Date: 2021/6/13
Time: 22:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form:form modelAttribute="person" method="post" action="/validator/register">
用户名:<form:input path="username" autocomplete="false"/><form:errors path="username"/><br>
密码:<form:password path="password" autocomplete="false"/><form:errors path="password"/><br>
邮箱:<form:input path="email" autocomplete="false"/><form:errors path="email"/><br>
电话:<form:input path="phone" autocomplete="false"/><form:errors path="phone"/><br>
<input type="submit" value="提交"/>
</form:form>
</body>
</html>
校验规则详解:
@Null 被注解的元素必须为null
@NotNull 被注解的元素不能为null
@Min(value) 被注解的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注解的元素必须是一个数字,其值必须小于于等于指定的最大值
@Email 被注解的元素必须是电子邮箱地址
@Pattern 被注解的元素必须符合对应的正则表达式
@Length 被注解的元素的大小必须在指定的范围内
@NotEmpty 被注解的字符串的值必须非空
Null 和 Empty 是不同的结果,String str = null,str 是 null,String str = “”,str 不是 null,其值为空。