SpringMVC入门终结篇

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC入门终结篇相关的知识,希望对你有一定的参考价值。

SpringMVC入门第四部分

自定义类型对象和请求参数的数据绑定流程

在这里插入图片描述
在这里插入图片描述


自定义类型转换器

自定义类型转换器,实现String----->employee对象的转换和封装

<form action="${ctp}/quickAdd">
    <%--将员工所有信息都写上,自动封装对象--%>
     <input type="text" name="empInfo" value="大忽悠-总裁办-@123-1"/>
   <input type="submit" value="快速添加员工"/>
</form>

快速添加员工的方法:

    @RequestMapping("quickAdd")
    //获取请求参数empInfo
    //employee=request.getParame("empInfo")---->大忽悠-总裁办-@123-1
    public String quickAdd(@RequestParam("empInfo") Employee employee)
    {
        employeeDao.save(employee);
      return  "redirect:/emps";
    }

ConversionService是一个接口,里面通过一个Converter转换器进行工作

在这里插入图片描述


步骤1:实现Converter接口,写一个自定义类型转换器

/*
* 两个泛型S,T
* S:source
* T:target
* 把s转换为t
* */
//自定义类型转换器
public class MyConverter implements Converter<String, Employee> {
    //自定义转换规则
    public Employee convert(String source) {
        System.out.println("要转换的字符串:"+source);
        Employee employee=new Employee();
        if(source.contains("-"))
        {
            //大忽悠-总裁办-@123-1
            String[] ret=source.split("-");
            employee.setName(ret[0]);
            employee.setDepartment(ret[1]);
            employee.setEamil(ret[2]);
            employee.setGender(Integer.parseInt(ret[3]));
        }
        return employee;
    }
}

步骤2:Converter是ConversionService中的一个组件,我们需要把Converter放入到ConversionService中

步骤3:将WebDataBinder中的ConversionService设置成我们这个加了自定义类型ConversionService

步骤4:让SpringMVC使用我们的ConversionService

配置文件中实现步骤1:配置出ConversionService


converters在源码中是一个set集合
在这里插入图片描述


    <!--告诉SpringMVC别用默认的ConversionService,
    而是使用自定义的ConversionService
    ,里面有我们自定义的converter-->
    <bean id="conversionService"
          class="org.springframework.context.support.ConversionServiceFactoryBean">
        <!--在converters转换器中添加我们自定义的类型转换器-->
        <property name="converters">
            <set>
                <bean class="com.Converter.MyConverter"/>
            </set>
        </property>
    </bean>
    <!--使用我们自己的配置的类型转换组件-->
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

在这里插入图片描述

总结三步

在这里插入图片描述
在这里插入图片描述


annotation-driven介绍

在这里插入图片描述

mvc:annotation-driven和mvc:default对动态和静态资源的影响

当mvc:annotation-driven和mvc:default-servlet-handler都没配置时,只有动态资源能够访问,静态资源访问不了

在这里插入图片描述
在这里插入图片描述

常见动态资源: @RequestMapping映射的资源,.jsp

常见的静态资源: .html , .js , .img


只加mvc:default-servlet-handler,那么静态资源能访问,动态资源不能访问

在这里插入图片描述在这里插入图片描述


只配置mvc:annotation-driven,那么只能访问动态资源,不能访问静态资源


mvc:default-servlet-handler和mvc:annotation-driven都配置后,那么静态资源和动态资源都可以访问了


数据格式化之日期格式化

在这里插入图片描述

ConversionServiceFactoryBean创建的ConversionService组件是没有格式化器存在的

解决方法1:不使用自定义类型的转换器

在这里插入图片描述

解决方法2:将自定义类型转换器注册到FormattingConversionServiceFactoryBean,这样就有格式化功能了

以后写自定义数据类型转换器的时候,就使用FormattingConversionServiceFactoryBean来注册自定义类型转换器,这样就既具有类型转换,又具有格式化功能

    <bean id="conversionService"
          class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <!--在converters转换器中添加我们自定义的类型转换器-->
        <property name="converters">
            <set>
                <bean class="com.Converter.MyConverter"/>
            </set>
        </property>
    </bean>
    <!--使用我们自己的配置的类型转换组件-->
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

后端规定提交的日期格式,不对就报错

//规定提交的日期格式
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


后端规定提交的数字格式

@NumberFormat(pattern = "#,###,###.##")//类似这样的数字格式: 1,000,000.98
private double salary;

数据校验:只做前端校验是不安全的,在重要的数据一定要加上后端校验

SpingMVC可以使用JSR303来做数据校验

在这里插入图片描述
在这里插入图片描述

Hibernate Validator是第三方框架实现了JSR303规范

在这里插入图片描述


实现步骤:

1.maven管理引入springmvc注解数据校验所需jar包:

   <!-- maven管理引入springmvc注解数据校验所需jar包:-->
    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>1.1.0.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.1.0.Final</version>
    </dependency>

2.只需要给javaBean的属性上加上校验注解

@NotEmpty
@Length(min=6,max=8)//至少6个字符,最多8个字符
private  String name;
private  String department;
@Email
private  String eamil;

3.在SpringMVC封装对象的时候,告诉SpringMVC这个javaBean对象需要校验----@Valid注解

   //只接收Post请求
    @RequestMapping(value = "/emp",method = RequestMethod.POST)
    //@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
    public String addEmp(@Valid Employee employee)//这里会自动赋值
    {
        System.out.println("要添加的员工信息:"+employee);
            employeeDao.save(employee);
            //返回列表页面,直接重定向到查询所有员工的请求
            return  "redirect:/emps";
    }

4.如何知道校验结果,给需要校验的javaBean后面紧跟一个BindingResult,这个BindingResult就是封装前一个bean的校验结果

    //只接收Post请求
    @RequestMapping(value = "/emp",method = RequestMethod.POST)
    //@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
    public String addEmp(@Valid Employee employee,BindingResult res)//这里会自动赋值
    {
        System.out.println("要添加的员工信息:"+employee);
            employeeDao.save(employee);
            //返回列表页面,直接重定向到查询所有员工的请求
            return  "redirect:/emps";
    }

5.根据不同的校验结果决定怎么做

    //只接收Post请求
    @RequestMapping(value = "/emp",method = RequestMethod.POST)
    //@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
    public String addEmp(@Valid Employee employee,BindingResult res)//这里会自动赋值
    {
        System.out.println("要添加的员工信息:"+employee);
        //获取是否有校验错误
        boolean hasErrors = res.hasErrors();
        if(hasErrors)
        {
            System.out.println("有校验错误");
            return "addPage";
        }
        else
        {
            employeeDao.save(employee);
            //返回列表页面,直接重定向到查询所有员工的请求
            return  "redirect:/emps";
        }
    }

6.将错误信息回显在页面上

<%pageContext.setAttribute("ctp",request.getContextPath());%>
<form:form modelAttribute="employee" action="${ctp}/emp" method="post">
    <%--显示错误信息,有默认的错误信息,也可也自己写显示的错误西信息--%>
    员工id:<form:input path="id"/><form:errors path="id"></form:errors><br/>
    姓名:<form:input path="name"/><form:errors path="name"></form:errors><br/>
    邮箱:<form:input path="eamil"/><form:errors path="eamil"></form:errors><br/>
    性别:<br/>
    男:<form:radiobutton path="gender" value="1"/>
    女:<form:radiobutton path="gender" value="0"/>
    请选择员工所在的部门:
    <form:select path="department" items="${departments}"/>
    <br/>
    <input type="submit" value="提交">
</form:form>

普通表单将请求信息放在请求域中去页面获取

通过BindingResult的res对象的 getFieldErrors方法,可以获得当前属性值出现的全部错误,然后通过一个Model对象存储错误信息,放到隐含模型中

    //只接收Post请求
    @RequestMapping(value = "/emp",method = RequestMethod.POST)
    //@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
    public String addEmp(@Valid Employee employee,BindingResult res,Model model)//这里会自动赋值
    {
        System.out.println("要添加的员工信息:"+employee);
        //获取是否有校验错误
        boolean hasErrors = res.hasErrors();
        Map<String,String> errorMap=new HashMap<String, String>();
        if(hasErrors)
        {
            List<FieldError> fieldErrors = res.getFieldErrors();
            for(FieldError fieldError:fieldErrors)
            {
                System.out.println("错误消息提示:"+fieldError.getDefaultMessage());
                System.out.println("错误的字段:"+fieldError.getField());
                System.out.println(fieldError);
                System.out.println("----------------------------------------");
                errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
            model.addAttribute("errorInfo",errorMap);
            System.out.println("有校验错误");
            return "addPage";
        }
        else
        {
            employeeDao.save以上是关于SpringMVC入门终结篇的主要内容,如果未能解决你的问题,请参考以下文章

SpringMVC入门系列篇3:@RequestMapping & @RequestHeader & @CookieValue详解与REST风格请求

SpringMVC详解------基于注解的入门实例

跟我一起学docker(18)--持续集成(初级终结篇)

浏览器渲染 理解终结篇

SSM 框架集-01-详细介绍-入门问题篇

Spring Boot 2.0 WebFlux 教程 | 入门篇