(1)SpringMVC的申请解决
1、SpringMVC对申请参数的解决
在之前的servlet中咱们能够通过request.getParameter()来获取申请中的参数,然而在咱们编写的SpringMVC的应用程序中,在具体申请的办法中并不蕴含request参数,那么咱们应该如何获取申请中的参数呢?
须要应用以下几个注解:
@RequestParam:获取申请的参数
@RequestHeader:获取申请头信息
@CookieValue:获取cookie中的值
@RequestParam的根本应用
package com.mashibing.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;@Controllerpublic class RequestController { /** * 如何获取SpringMVC中申请中的信息 * 默认状况下,能够间接在办法的参数中填写跟申请一样的名称,此时会默认承受参数 * 如果有值,间接赋值,如果没有,那么间接给空值 * * @RequestParam:获取申请中的参数值,应用此注解之后,参数的名称不须要跟申请的名称统一,然而必须要写 * public String request(@RequestParam("user") String username){ * * 此注解还蕴含三个参数: * value:示意要获取的参数值 * required:示意此参数是否必须,默认是true,如果不写参数那么会报错,如果值为false,那么不写参数不会有任何谬误 * defaultValue:如果在应用的时候没有传递参数,那么定义默认值即可 * * * @param username * @return */ @RequestMapping("/request") public String request(@RequestParam(value = "user",required = false,defaultValue = "hehe") String username){ System.out.println(username); return "success"; }}
@RequestHeader的根本应用:
package com.mashibing.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestHeader;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import sun.management.resources.agent;@Controllerpublic class RequestController { /** * 如果须要获取申请头信息该如何解决呢? * 能够应用@RequestHeader注解, * public String header(@RequestHeader("User-Agent") String agent){ * 相当于 request.getHeader("User-Agent") * * 如果要获取申请头中没有的信息,那么此时会报错,同样,此注解中也蕴含三个参数,跟@RequestParam一样 * value * required * defalutValue * @param agent * @return */ @RequestMapping("/header") public String header(@RequestHeader("User-Agent") String agent){ System.out.println(agent); return "success"; }}
@CookieValue的根本应用
package com.mashibing.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.CookieValue;import org.springframework.web.bind.annotation.RequestHeader;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import sun.management.resources.agent;@Controllerpublic class RequestController { /** * 如果须要获取cookie信息该如何解决呢? * 能够应用@CookieValue注解, * public String cookie(@CookieValue("JSESSIONID") String id){ * 相当于 * Cookie[] cookies = request.getCookies(); * for(Cookie cookie : cookies){ * cookie.getValue(); * } * 如果要获取cookie中没有的信息,那么此时会报错,同样,此注解中也蕴含三个参数,跟@RequestParam一样 * value * required * defalutValue * @param id * @return */ @RequestMapping("/cookie") public String cookie(@CookieValue("JSESSIONID") String id){ System.out.println(id); return "success"; }}
如果申请中传递的是某一个对象的各个属性值,此时如何在控制器的办法中获取对象的各个属性值呢?
在SpringMVC的管制中,能间接实现对象的属性赋值操作,不须要人为干涉。
User.java
package com.mashibing.bean;import java.util.Date;public class User { private Integer id; private String name; private Integer age; private Date date; private Address address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", date=" + date + ", address=" + address + '}'; }}
Address.java
package com.mashibing.bean;public class Address { private String province; private String city; private String town; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getTown() { return town; } public void setTown(String town) { this.town = town; } @Override public String toString() { return "Address{" + "province='" + province + '\'' + ", city='" + city + '\'' + ", town='" + town + '\'' + '}'; }}
login.jsp
<%-- Created by IntelliJ IDEA. User: root Date: 2020/3/7 Time: 0:11 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body><form action="addUser" method="post"> 编号:<input type="text" name="id"/><br> 姓名:<input type="text" name="name"/><br> 年龄:<input type="text" name="age"/><br> 日期:<input type="text" name="date"/><br> 省份:<input type="text" name="address.province"/><br> 城市:<input type="text" name="address.city"/><br> 区域:<input type="text" name="address.town"/><br> <input type="submit" value="submit"/><br></form></body></html>
UserController.java
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class UserController { @RequestMapping("/addUser") public String addUser(User user){ System.out.println(user); return "success"; }}
2、乱码问题的解决
咱们在表单或者发送申请的时候,常常会遇到中文乱码的问题,那么如何解决乱码问题呢?
GET申请:在server.xml文件中,增加URIEncoding=“UTF-8”
POST申请:编写过滤器进行实现
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置DispatcherServlet--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 关联springmvc的配置文件: 此配置文件的属性能够不增加,然而须要在WEB-INF的目录下创立 前端控制器名称-servlet.xml文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> </servlet> <!--匹配servlet的申请, /:标识匹配所有申请,然而不会jsp页面 /*:拦挡所有申请,拦挡jsp页面 然而须要留神的是,当配置成index.html的时候,会发现申请不到 起因在于,tomcat下也有一个web.xml文件,所有的我的项目下web.xml文件都须要继承此web.xml 在服务器的web.xml文件中有一个DefaultServlet用来解决动态资源,然而url-pattern是/ 而咱们在本人的配置文件中如果增加了url-pattern=/会笼罩父类中的url-pattern,此时在申请的时候 DispatcherServlet会去controller中做匹配,找不到则间接报404 而在服务器的web.xml文件中蕴含了一个JspServlet的解决,所以不过拦挡jsp申请 --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!--解决post申请乱码--> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <!--解决响应乱码--> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping></web-app>
留神:如果配置了多个过滤器,那么字符编码过滤器肯定要在最后面,否则生效。
3、SpringMVC对原生API的反对
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.ServletInputStream;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.BufferedReader;import java.io.PrintWriter;@Controllerpublic class UserController { @RequestMapping("/addUser") public String addUser(User user){ System.out.println(user); return "success"; } /** * SpringMVC也能够在参数上应用原生的Servlet API * * HttpSession * HttpServletRequest * HttpServletResponse * * java.security.Principal 平安协定相干 * Locale:国际化相干的区域信息对象 * InputStream: * ServletInputStream inputStream = request.getInputStream(); * OutputStream: * ServletOutputStream outputStream = response.getOutputStream(); * Reader: * BufferedReader reader = request.getReader(); * Writer: * PrintWriter writer = response.getWriter(); * @param session * @param request * @param response * @return */ @RequestMapping("api") public String api(HttpSession session, HttpServletRequest request, HttpServletResponse response){ request.setAttribute("requestParam","request"); session.setAttribute("sessionParam","session"); return "success"; }}
4、应用Model,Map,ModelMap传输数据到页面
在刚开始的helloworld我的项目中,咱们传递了参数回到咱们页面,然而后续的操作都只是承受用户的申请,那么在SpringMVC中除了能够应用原生servlet的对象传递数据之外,还有什么其余的形式呢?
能够在办法的参数上传入Model,ModelMap,Map类型,此时都可能将数据传送回页面
OutputController.java
package com.mashibing.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import java.util.Map;@Controllerpublic class OutputController { @RequestMapping("output1") public String output1(Model model){ model.addAttribute("msg","hello,Springmvc"); return "output"; } @RequestMapping("output2") public String output2(ModelMap model){ model.addAttribute("msg","hello,Springmvc"); return "output"; } @RequestMapping("output3") public String output1(Map map){ map.put("msg","hello,Springmvc"); return "output"; }}
当应用此形式进行设置之后,会发现所有的参数值都设置到了request作用域中,那么这三个对象是什么关系呢?
5、应用ModelAndView对象传输数据到页面
package com.mashibing.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controllerpublic class OutputController { @RequestMapping("mv") public ModelAndView mv(){ ModelAndView mv = new ModelAndView(); mv.setViewName("output"); mv.addObject("msg","hello.modelAndView"); return mv; }}
发现当应用modelAndView对象的时候,返回值的类型也是此对象,能够将要跳转的页面设置成view的名称,来实现跳转的性能,同时数据也是放到request作用中。
6、应用session传输数据到页面
@SessionAttribute:此注解能够示意,当向request作用域设置数据的时候同时也要向session中保留一份,此注解有两个参数,一个value(示意将哪些值设置到session中),另外一个type(示意依照类型来设置数据,个别不必,因为有可能会将很多数据都设置到session中,导致session异样)。
@Controller@SessionAttributes(value = "msg")public class OutputController { @RequestMapping("output1") public String output1(Model model){ model.addAttribute("msg","hello,Springmvc"); System.out.println(model.getClass()); return "output"; }}
7、应用@ModelAttribute来获取申请中的数据
@ModelAttribute注解用于将办法的参数或者办法的返回值绑定到指定的模型属性上,并返回给web视图。首先来介绍一个业务场景,来帮忙大家做了解,在理论工作中,有些时候咱们在批改数据的时候可能只须要批改其中几个字段,而不是全副的属性字段都获取,那么当提交属性的时候,从form表单中获取的数据就有可能只蕴含了局部属性,此时再向数据库更新的时候,必定会失落属性,因为对象的封装是springmvc主动帮咱们new的,所以此时须要先将从数据库获取的对象保留下来,当提交的时候不是new新的对象,而是在原来的对象上进行属性笼罩,此时就须要应用@ModelAttribute注解。
User.java
package com.mashibing.bean;public class User { private Integer id; private String name; private String password; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", password='" + password + '\'' + ", age=" + age + '}'; }}
UserController.java
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class UserController { Object o1 = null; Object o2 = null; Object o3 = null; @RequestMapping("update") public String update(@ModelAttribute("user") User user,Model model){ System.out.println(user); o2 = model; //能够看到所有的model都是同一个对象 System.out.println(o1==o2); //能够看到存储的user对象也是同一个 System.out.println(user == o3); return "output"; } @ModelAttribute public void MyModelAttribute(Model model){ o1 = model; User user = new User(); user.setId(1); user.setName("张三"); user.setAge(12); user.setPassword("123"); model.addAttribute("user",user); System.out.println("modelAttribute:"+user); o3 = user; }}
index.jsp
<%-- Created by IntelliJ IDEA. User: root Date: 2020/3/11 Time: 13:45 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html> <head> <title>$Title$</title> </head> <body> <form action="update" method="post"> <input type="hidden" value="1" name="id"> 姓名:张三<br> 明码:<input type="text" name="password"><br> 年龄:<input type="text" name="age"><br> <input type="submit" value="提交"> </form> </body></html>
其实在应用的时候能够简化写法,也就是说,在办法的参数上不加@ModelAttribute也不会有问题
@RequestMapping("update") public String update(User user,Model model){ System.out.println(user); o2 = model; //能够看到所有的model都是同一个对象 System.out.println(o1==o2); //能够看到存储的user对象也是同一个 System.out.println(user == o3); return "output"; }
如果增加的@ModelAttribute(“”)属性的值不对,那么也是获取不到值的。同时能够增加@SessionAttributes属性,然而留神,如果没有设置值的话,会报错
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.SessionAttributes;@Controller@SessionAttributes("u")public class UserController { Object o1 = null; Object o2 = null; Object o3 = null; @RequestMapping("update") public String update(@ModelAttribute("u") User user,Model model){ System.out.println(user); o2 = model; //能够看到所有的model都是同一个对象 System.out.println(o1==o2); //能够看到存储的user对象也是同一个 System.out.println(user == o3); return "output"; } @ModelAttribute public void MyModelAttribute(Model model){ o1 = model; User user = new User(); user.setId(1); user.setName("张三"); user.setAge(12); user.setPassword("123"); model.addAttribute("user",user); System.out.println("modelAttribute:"+user); o3 = user; }}
留神:ModelAttribute除了能够应用设置值到model中之外,还能够利用返回值。
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.SessionAttributes;@Controllerpublic class UserController { Object o1 = null; Object o2 = null; Object o3 = null; @RequestMapping("update") public String update(@ModelAttribute("u") User user,Model model){ System.out.println(user); o2 = model; //能够看到所有的model都是同一个对象 System.out.println(o1==o2); //能够看到存储的user对象也是同一个 System.out.println(user == o3); return "output"; } @ModelAttribute("u") public User MyModelAttribute(Model model){ o1 = model; User user = new User(); user.setId(1); user.setName("张三"); user.setAge(12); user.setPassword("123");// model.addAttribute("user",user); System.out.println("modelAttribute:"+user); o3 = user; return user; }}
总结:通过刚刚的给参数赋值,大家应该可能发现,当给办法中的参数设置值的时候,如果增加了@ModelAttribute注解,那么在查找值的时候,是遵循以下形式:
1、办法的参数应用参数的类型首字母小写,或者应用@ModelAttribute("")的值
2、先看之前是否在model中设置过该属性值,如果设置过就间接获取
3、看@SessionAttributes注解标注类中的办法是否给session中赋值,如果有的话,也是间接获取,没有报异样
8、应用forward实现页面转发
在发送申请的时候,能够通过forward:来实现转发的性能:
package com.mashibing.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class ForWardController { /** * 当应用转发的时候能够增加前缀forward:index.jsp,此时是不会通过视图解析器的,所以要增加残缺的名称 * * forward:也能够由一个申请跳转到另外一个申请 * * @return */ @RequestMapping("/forward01") public String forward(){ System.out.println("1"); return "forward:/index.jsp"; } @RequestMapping("/forward02") public String forward2(){ System.out.println("2"); return "forward:/forward01"; }}
9、应用redirect来实现重定向
package com.mashibing.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class RedirectController { /** * redirect :重定向的门路 * 相当于 response.sendRedirect("index.jsp") * 跟视图解析器无关 * @return */ @RequestMapping("redirect") public String redirect(){ System.out.println("redirect"); return "redirect:/index.jsp"; } @RequestMapping("/redirect2") public String redirect2(){ System.out.println("redirect2"); return "redirect:/redirect"; }}
在javaweb的时候大家应该都接触过重定向和转发的区别,上面再具体说一下:
转发:
由服务器的页面进行跳转,不须要客户端从新发送申请:
特点如下:
1、地址栏的申请不会发生变化,显示的还是第一次申请的地址
2、申请的次数,有且仅有一次申请
3、申请域中的数据不会失落
4、根目录:localhost:8080/我的项目地址/,蕴含了我的项目的拜访地址
重定向:
在浏览器端进行页面的跳转,须要发送两次申请(第一次是人为的,第二次是主动的)
特点如下:
1、地址栏的地址发生变化,显示最新发送申请的地址
2、申请次数:2次
3、申请域中的数据会失落,因为是不同的申请
4、根目录:localhost:8080/ 不蕴含我的项目的名称
比照:
区别 | 转发forward() | 重定向sendRedirect() |
---|---|---|
根目录 | 蕴含我的项目拜访地址 | 没有我的项目拜访地址 |
地址栏 | 不会发生变化 | 会发生变化 |
哪里跳转 | 服务器端进行的跳转 | 浏览器端进行的跳转 |
申请域中数据 | 不会失落 | 会失落 |
10、动态资源的拜访
当页面中蕴含动态资源的时候咱们可能正确的获取到吗?
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %><% pageContext.setAttribute("ctx",request.getContextPath());%><html><head> <title>Title</title></head><body>hello springmvc<img src="${ctx}/images/timg.jpg"></body></html>
此时大家发现咱们申请的图片基本拜访不到,依据查看发现门路是没有问题的,那么为什么会找不到动态资源呢?
大家发现此时是找不到对应的mapping映射的,此时是因为DispatcherServlet会拦挡所有的申请,而此时咱们没有对应图片的申请解决办法,所以此时报错了,想要解决的话非常简单,只须要增加一个配置即可
<!--此配置示意 咱们本人配置的申请由controller来解决,然而不能申请的解决交由tomcat来解决动态资源能够拜访,然而动静申请无法访问--><mvc:default-servlet-handler/>
然而加上此配置之后,大家又发现此时除了动态资源无法访问之外,咱们失常的申请也无奈获取了,因而还须要再增加另外的配置:
<!--保障动态资源和动静申请都可能拜访--><mvc:annotation-driven/>
(2)自定义视图解析器
咱们在之前的操作中曾经用了SpringMVC中提供的视图解析器,那么如果咱们须要实现本人的视图解析器该如何操作呢?
MyViewController.java
package com.mashibing.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class MyViewController { @RequestMapping("/myview") public String myView(Model model){ model.addAttribute("msb","马士兵"); return "msb:/index"; }}
MyViewResolver.java
package com.mashibing.view;import org.springframework.core.Ordered;import org.springframework.web.servlet.View;import org.springframework.web.servlet.ViewResolver;import java.util.Locale;public class MyViewResolver implements ViewResolver, Ordered { private int order = 0; public View resolveViewName(String viewName, Locale locale) throws Exception { //如果前缀是msb:结尾的就进行解析 if (viewName.startsWith("msb:")){ System.out.println("msb:"); return new MyView(); }else{ //如果不是,则间接返回null return null; } } public int getOrder() { return this.order; } public void setOrder(Integer order) { this.order = order; }}
MyView.java
package com.mashibing.view;import org.springframework.core.Ordered;import org.springframework.web.servlet.View;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.Map;public class MyView implements View { public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("保留的对象是:"+model); response.setContentType("text/html"); response.getWriter().write("欢送退出马士兵教育"); } /** * 返回数据内容的类型 * @return */ public String getContentType() { return "text/html"; }}
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.mashibing"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/page/"></property> <property name="suffix" value=".jsp"></property> </bean> <bean class="com.mashibing.view.MyViewResolver"> <property name="order" value="1"></property> </bean></beans>
(3)自定义类型转换器
在日常的企业开发需要中,咱们输出文本框的内容全部都是字符串类型,然而在后端解决的时候咱们能够用其余根本类型来承受数据,也能够应用实体类来承受参数,这个是怎么实现的呢?就是通过SpringMVC提供的类型转换器,SpringMVC外部提供了十分丰盛的类型转换器的反对,然而有些状况下有可能难以满足咱们的需要,因而须要咱们本人实现,如下:
User.java
package com.mashibing.bean;public class User { private Integer id; private String name; private Integer age; private String gender; public User() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", gender='" + gender + '\'' + '}'; }}
MyConverter.java
package com.mashibing.converter;import com.mashibing.bean.User;import org.springframework.core.convert.converter.Converter;import org.springframework.stereotype.Component;@Componentpublic class MyConverter implements Converter<String, User> { public User convert(String source) { User user = null; String[] split = source.split("-"); if (source!=null && split.length==4){ user = new User(); user.setId(Integer.parseInt(split[0])); user.setName(split[1]); user.setAge(Integer.parseInt(split[2])); user.setGender(split[3]); } return user; }}
UserController.java
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class UserController { @RequestMapping("/user") public String add(User user, Model model){ System.out.println(user); model.addAttribute("user","user"); return "success"; }}
success.jsp
<%-- Created by IntelliJ IDEA. User: root Date: 2020/3/12 Time: 21:36 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body>${requestScope.user}</body></html>
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.mashibing"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/page/"></property> <property name="suffix" value=".jsp"></property> </bean> <bean class="com.mashibing.view.MyViewResolver"> <property name="order" value="1"></property> </bean> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <ref bean="myConverter"></ref> </set> </property> </bean></beans>
(4)自定义日期格式化转换器
有时候咱们常常须要在页面增加日期等相干信息,此时须要制订日期格式化转换器,此操作非常简单:只须要在独自的属性上增加@DateTimeFormat注解即可,制订对应的格局
User.java
package com.mashibing.bean;import org.springframework.format.annotation.DateTimeFormat;import java.util.Date;public class User { private Integer id; private String name; private Integer age; private String gender; @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birth; public User() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", gender='" + gender + '\'' + ", birth=" + birth + '}'; }}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html> <head> <title>$Title$</title> </head> <body><form action="dateConvertion" method="post"> 编号:<input type="text" name="id"><br> 姓名:<input type="text" name="name"><br> 年龄:<input type="text" name="age"><br> 性别:<input type="text" name="gender"><br> 日期:<input type="text" name="birth"><br> <input type="submit" value="提交"></form> </body></html>
DateConvertionController.java
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class DateConvertionController { @RequestMapping("dateConvertion") public String dateConvertion(User user){ System.out.println(user); return "hello"; }}
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.mashibing"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/page/"></property> <property name="suffix" value=".jsp"></property> </bean> <bean class="com.mashibing.view.MyViewResolver"> <property name="order" value="1"></property> </bean> <!--此配置示意 咱们本人配置的申请由controller来解决,然而不能申请的解决交由tomcat来解决 动态资源能够拜访,然而动静申请无法访问 --> <mvc:default-servlet-handler/> <!--保障动态资源和动静申请都可能拜访--> <mvc:annotation-driven></mvc:annotation-driven></beans>
此时运行发现是没有问题的,然而须要留神的是,如果同时配置了自定义类型转换器之后,那么日期格局转化是有问题的。
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.mashibing"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/page/"></property> <property name="suffix" value=".jsp"></property> </bean> <bean class="com.mashibing.view.MyViewResolver"> <property name="order" value="1"></property> </bean> <!--此配置示意 咱们本人配置的申请由controller来解决,然而不能申请的解决交由tomcat来解决 动态资源能够拜访,然而动静申请无法访问 --> <mvc:default-servlet-handler/> <!--保障动态资源和动静申请都可能拜访--> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <ref bean="myConverter"></ref> </set> </property> </bean></beans>
起因就在于ConversionServiceFactoryBean对象中有且仅有一个属性converters,此时能够应用另外一个类来做替换FormattingConversionServiceFactoryBean
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.mashibing"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/page/"></property> <property name="suffix" value=".jsp"></property> </bean> <bean class="com.mashibing.view.MyViewResolver"> <property name="order" value="1"></property> </bean> <!--此配置示意 咱们本人配置的申请由controller来解决,然而不能申请的解决交由tomcat来解决 动态资源能够拜访,然而动静申请无法访问 --> <mvc:default-servlet-handler/> <!--保障动态资源和动静申请都可能拜访--><!-- <mvc:annotation-driven></mvc:annotation-driven>--> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <ref bean="myConverter"></ref> </set> </property> </bean></beans>
(5)数据校验
个别状况下咱们会在前端页面实现数据的校验,然而大家须要留神的是前端校验会存在数据的不平安问题,因而个别状况下咱们都会应用前端校验+后端校验的形式,这样的话既可能满足用户的体验度,同时也能保证数据的平安,上面来说一下在springmvc中如何进行后端数据校验。
JSR303是 Java 为 Bean 数据合法性校验提供的规范框架,它曾经蕴含在 JavaEE 6.0 中 。JSR 303 (Java Specification Requests意思是Java 标准提案)通过在 Bean 属性上标注相似于 @NotNull、@Max 等规范的注解指定校验规定,并通过规范的验证接口对 Bean 进行验证。
JSR303:
Hibernate Validator 扩大注解:
spring中领有本人的数据校验框架,同时反对JSR303规范的校验框架,能够在通过增加注解的形式进行数据校验。在spring中自身没有提供JSR303的实现,须要导入依赖的包。
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mashibing</groupId> <artifactId>springmvc_viewResolver</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.3.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.0.Final</version> </dependency> </dependencies></project>
index.jsp
<%-- Created by IntelliJ IDEA. User: root Date: 2020/3/12 Time: 15:23 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html> <head> <title>$Title$</title> </head> <body><form action="dataValidate" method="post"> 编号:<input type="text" name="id"><br> 姓名:<input type="text" name="name"><br> 年龄:<input type="text" name="age"><br> 性别:<input type="text" name="gender"><br> 日期:<input type="text" name="birth"><br> 邮箱:<input type="text" name="email"><br> <input type="submit" value="提交"></form> </body></html>
DataValidateController.java
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.validation.BindingResult;import org.springframework.web.bind.annotation.RequestMapping;import javax.validation.Valid;@Controllerpublic class DataValidateController { @RequestMapping("/dataValidate") public String validate(@Valid User user, BindingResult bindingResult) { System.out.println(user); if (bindingResult.hasErrors()) { System.out.println("验证失败"); return "redirect:/index.jsp"; } else { System.out.println("验证胜利"); return "hello"; } }}
User.java
package com.mashibing.bean;import org.hibernate.validator.constraints.Email;import org.hibernate.validator.constraints.Length;import org.springframework.format.annotation.DateTimeFormat;import javax.validation.constraints.NotNull;import javax.validation.constraints.Past;import java.util.Date;public class User { private Integer id; @NotNull @Length(min = 5,max = 10) private String name; private Integer age; private String gender; @Past @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birth; @Email private String email; public User() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", gender='" + gender + '\'' + ", birth=" + birth + ", email='" + email + '\'' + '}'; }}
此时大家发现在报错的中央无奈呈现谬误提醒,能够换另外一种形式:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html> <head> <title>$Title$</title> </head> <body><a href="add">增加用户</a> </body></html>
add.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>$Title$</title></head><body><form:form action="dataValidate" modelAttribute="user" method="post"> id:<form:input path="id"></form:input><form:errors path="id"></form:errors> <br/> name:<form:input path="name"></form:input><form:errors path="name"></form:errors><br/> age:<form:input path="age"></form:input><form:errors path="age"></form:errors><br/> gender:<form:input path="gender"></form:input><form:errors path="gender"></form:errors><br/> birth:<form:input path="birth"></form:input><form:errors path="birth"></form:errors><br/> email:<form:input path="email"></form:input><form:errors path="email"></form:errors><br/> <input type="submit" value="submit"></form:form></body></html>
DataValidateController.java
package com.mashibing.controller;import com.mashibing.bean.User;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.validation.BindingResult;import org.springframework.web.bind.annotation.RequestMapping;import javax.validation.Valid;@Controllerpublic class DataValidateController { @RequestMapping("/dataValidate") public String validate(@Valid User user, BindingResult bindingResult, Model model) { System.out.println(user); if (bindingResult.hasErrors()) { System.out.println("验证失败"); return "add"; } else { System.out.println("验证胜利"); return "hello"; } } @RequestMapping("add") public String add(Model model){ model.addAttribute("user",new User(1,"zhangsan",12,"女",null,"1234@qq.com")); return "add"; }}
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </context-param> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping></web-app>
原生的表单如何获取错误信息:
DataValidateController.java
package com.mashibing.controller;import com.mashibing.bean.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.RequestMapping;import javax.validation.Valid;import java.util.HashMap;import java.util.List;import java.util.Map;@Controllerpublic class DataValidateController { @RequestMapping("/dataValidate") public String validate(@Valid User user, BindingResult bindingResult, Model model) { System.out.println(user); Map<String,Object> errorsMap = new HashMap<String, Object>(); if (bindingResult.hasErrors()) { System.out.println("验证失败"); List<FieldError> fieldErrors = bindingResult.getFieldErrors(); for (FieldError fieldError : fieldErrors) { System.out.println(fieldError.getDefaultMessage()); System.out.println(fieldError.getField()); errorsMap.put(fieldError.getField(),fieldError.getDefaultMessage()); } model.addAttribute("errorInfo",errorsMap); return "add"; } else { System.out.println("验证胜利"); return "hello"; } } @RequestMapping("add") public String add(Model model){ model.addAttribute("user",new User(1,"zhangsan",12,"女",null,"1234@qq.com")); return "add"; }}
add.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>$Title$</title></head><body><form:form action="dataValidate" modelAttribute="user" method="post"> 编号:<form:input path="id"></form:input><form:errors path="id"></form:errors>--->${errorInfo.id} <br/> 姓名:<form:input path="name"></form:input><form:errors path="name"></form:errors>--->${errorInfo.name}<br/> 年龄:<form:input path="age"></form:input><form:errors path="age"></form:errors>--->${errorInfo.age}<br/> 性别:<form:input path="gender"></form:input><form:errors path="gender"></form:errors>--->${errorInfo.gender}<br/> 生日:<form:input path="birth"></form:input><form:errors path="birth"></form:errors>--->${errorInfobirth}<br/> 邮箱:<form:input path="email"></form:input><form:errors path="email"></form:errors>--->${errorInfo.email}<br/> <input type="submit" value="submit"></form:form></body></html>