(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>