springmvc基于注解的使用(类型转换器&数据格式化&数据校验)

1、类型转换器

在SpringMvc中有许多的类型转换器,都在Convert这个接口下面定义着,但是有时候我们也会遇到我们需要转换的形式SpringMvc没有提供,我们就可以自定义一个类型转换器:

Convert接口类:

在这里插入图片描述

自定义类型转换器:
步骤在代码中:

import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author dujlc
 * 1、定义类型转换器    需要明确  源类型   目标类型
 * 2、在convert方法自定义类型的实现方法
 * 3、在SpringMvc中配置我们的自定义类型转换器
 * 4、在annotation-driven中加入自定义类型转换器
 */
public class MyStringToDateConvert implements Converter<String, Date> {
    public Date convert(String s) {
        if(!StringUtils.isEmpty(s)){
            try {
                if(s.split("-").length == 3){
                    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                        return df.parse(s);
                }
                if(s.split("/").length == 3){
                    DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
                    return df.parse(s);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

Spring配置文件中的配置:

<!-- 配置访问静态资源 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

<!-- 配置自定义类型转换器 -->
<!-- 如果需要注解的方式去支持日期格式转换,则需要改成org.springframework.format.support.FormattingConversionServiceFactoryBean类 -->
<bean class="org.springframework.context.support.ConversionServiceFactoryBean" name="conversionService">
    <property name="converters">
        <set>
            <bean class="cool.ale.convert.MyStringToDateConvert"></bean>
        </set>
    </property>
</bean>

2、数据格式化

我们可以使用到SpringMvc的标签库

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

主要作用就是对显示的数据进行格式化

2.1、提交时的jsp

<%--
  Created by IntelliJ IDEA.
  User: dujlc
  Date: 2021/6/3
  Time: 22:07
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <h1>添加用户</h1>
    <form action="${pageContext.request.contextPath}/addUser" method="post">
        <p>
            id:<input type="text" name="id" value="123"/>
        </p>
        <p>
            userName:<input type="text" name="userName" value="张三"/>
        </p>
        <p>
            birthday:<input type="text" name="birthday" value="2021/01/01"/>
        </p>
        <p>
            balance:<input type="text" name="balance" value="5000"/>
        </p>
        <p>
            salary:<input type="text" name="salary" value="10000"/>
        </p>
        <p>
            taskCount:<input type="text" name="taskCount" value="0.99"/>
        </p>
        <p>
            hobbies:<input type="checkbox" name="hobbies" name="唱歌" checked="true"/>唱歌
            <input type="checkbox" name="hobbies" name="跳舞" checked="true"/>跳舞
        </p>
        <p>
            <input type="submit" value="提交"/>
        </p>
    </form>

</body>
</html>

2.2、后端控制器

@Controller
public class UserController {
    @RequestMapping("/addUser")
    public String add(User user){
        System.out.println(user);
        return "show";
    }
}

2.3、实体类

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;

import java.util.Arrays;
import java.util.Date;

/**
 * @author dujlc
 */
public class User {
    private Integer id;
    private String userName;
    @DateTimeFormat(pattern = "yyyy/MM/dd")
    private Date birthday;

    /**
     * ¥5000
     */
    @NumberFormat(style = NumberFormat.Style.CURRENCY)
    private Double balance;

    /**
     * 工资  10,000.00
     */
    @NumberFormat(pattern = "#,###,##")
    private Double salary;

    /**
     * 任务完成比  90%
     */
    @NumberFormat(style = NumberFormat.Style.PERCENT)
    private Double taskCount;

    private String[] hobbies;
}

2.4、最后展示的jsp

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%--
  Created by IntelliJ IDEA.
  User: dujlc
  Date: 2021/6/3
  Time: 20: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>
    `<p>
        id:${user.id} <br/>
    </p>
    <p>
        userName:${user.userName} <br/>
    </p>
    <p>
        birthday: <spring:eval expression="user.birthday"></spring:eval><br/>
    </p>
    <p>
        balance:<spring:eval expression="user.balance"></spring:eval> <br/>
    </p>
    <p>
        salary:<spring:eval expression="user.salary"></spring:eval> <br/>
    </p>
    <p>
        taskCount:<spring:eval expression="user.taskCount"></spring:eval> <br/>
    </p>
    <p>
        hobbies: <spring:eval expression="user.hobbies"></spring:eval> <br/>
    </p>
</body>
</html>

3、数据格式化(hibernate-validate)

3.1、描述

前端数据校验有风险,所以后端也需要校验。
JSR303是Java为Bean数据合法性校验提供的标准,它已经包含在JavaEE6.0中。JSR303是通过在Bean属性上标注类似于@NotNull、@Max等标准的注解指定校验规则。
这个时候我们就需要了解一个hibernate-validate的东西,这个就是对我们的数据进行校验的。
所以我们需要导入hibernate-validate的依赖才可以去使用其中的注解,在mvn仓库中找到以下依赖并导入。

Mvn仓库地址
在这里插入图片描述

3.2、使用普通标签实现

1、加入hibernate-validate的依赖。
2、一定要注意!!将新加入的jar包加入到WEB-INF的lib文件夹下。
3、在javaBean的属性上面加上对应的注解,可以设置message属性提供更友好的提示信息。(特别注意:添加注解时导入的包一定时import javax.validation.constraints.下面的。)
4、在需要验证的对应的方法的参数上加上@Valid注解。
5、如果需要在当前页面显示错误,不需要直接抛出错误页面,可以参数中写入BindingResult result参数。
下面有注解示例和代码示例:

@Valid被注释的元素是一个对象,需要检查此对象的所有字段值
@Null被注释的元素必须为 null
@NotNull被注释的元素必须不为 null
@AssertTrue被注释的元素必须为 true
@AssertFalse被注释的元素必须为 false
@Min(value)指定最小值
@Max(value)指定最大值
@DecimalMin(value)指定最小值(且必须是数字)
@DecimalMax(value)指定最大值(且必须是数字)
@Size(max, min)指定的元素必须在某范围内
@Digits (integer, fraction)指定的元素必须在某范围内(且必须是数字)
@Past被注释的元素必须是一个过去的日期
@Future被注释的元素必须是一个将来的日期
@Pattern(value)被注释的元素必须符合指定的正则表达式

1、Person实体类

@NotNull
@Min(1)
private Integer id;

@NotEmpty
private String userName;

@Past(message = "输入的日期不能大于当前日期。")
private Date birthday;
private Double balance;

@Range(min = 2000,max = 10000)
private Double salary;

@Range(min = 0,max = 1)
private Double taskCount;
private String[] hobbies;

2、控制器类

/**
 * @author dujlc
 *
 * 基于原生form表单实现方式:
 * 1、在将错误信息循环通过map存入到request域中
 * 2、在jsp通过 ${errors.id} 获取到对应的错误信息
 */
@Controller
public class PersonController {
    @RequestMapping("/addPerson")
    public String add(@Valid Person person, BindingResult result, Model model){
        /*
         将错误信息取出来,输出到jsp页面
         */
        // 判断当前是否出现了错误
        if(result.hasErrors()){
            // 存放错误信息:key=错误信息的属性  value=错误信息
            // 这样就有利于在jsp中分别取出${errors.id}
            Map<String,String> errors = new HashMap<String, String>();
            // 获取所有的错误信息   包含  错误的属性,错误信息
            List<FieldError> fieldErrors = result.getFieldErrors();
            // 循环转移到Map中
            for(FieldError fieldError : fieldErrors){
                // fieldError.getField()是属性名
                // fieldError.getDefaultMessage()是错误信息
                errors.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
            model.addAttribute("errors",errors);
            // 如果验证失败, 将请求重新转发到添加页面
            // 当重新跳转时,我们的jsp页面上的值全都会存在request域中,直接取出来放到页面即可
            // <input type="text" name="salary" value="${person.salary}"/>
            // 就比如上面的 value="${person.salary}"
            return "user/addPerson";
        }
        System.out.println(person);
        return "showPerson";
    }
}

3、跳转之前的页面

<h1>添加用户</h1>
<form action="${pageContext.request.contextPath}/addPerson" method="post">
    <p>
        id:<input type="text" name="id" value="${person.id}"/><span style="color: red; ">${errors.id}</span>
    </p>
    <p>
        userName:<input type="text" name="userName" value="${person.userName}"/><span style="color: red; ">${errors.userName}</span>
    </p>
    <p>
        birthday:<input type="text" name="birthday" value="${person.birthday}"/><span style="color: red; ">${errors.birthday}</span>
    </p>
    <p>
        balance:<input type="text" name="balance" value="${person.balance}"/><span style="color: red; ">${errors.balance}</span>
    </p>
    <p>
        salary:<input type="text" name="salary" value="${person.salary}"/><span style="color: red; ">${errors.salary}</span>
    </p>
    <p>
        taskCount:<input type="text" name="taskCount" value="${person.taskCount}"/><span style="color: red; ">${errors.taskCount}</span>
    </p>
    <p>
        hobbies:<input type="checkbox" name="hobbies" name="唱歌" checked="true"/>唱歌
        <input type="checkbox" name="hobbies" name="跳舞" checked="true"/>跳舞
    </p>
    <p>
        <input type="submit" value="提交"/>
    </p>
</form>

4、跳转之后的页面

<body>
    <p>
        id:${person.id} <br/>
    </p>
    <p>
        userName:${person.userName} <br/>
    </p>
    <p>
        birthday: <spring:eval expression="person.birthday"></spring:eval><br/>
    </p>
    <p>
        balance:<spring:eval expression="person.balance"></spring:eval> <br/>
    </p>
    <p>
        salary:<spring:eval expression="person.salary"></spring:eval> <br/>
    </p>
    <p>
        taskCount:<spring:eval expression="person.taskCount"></spring:eval> <br/>
    </p>
    <p>
        hobbies: <spring:eval expression="person.hobbies"></spring:eval> <br/>
    </p>
</body>

3.3、使用form标签实现

jsp中导入form的标签库

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

1、给所有的form表单前面加上form:
2、将表单内的属性改成如下样式:

<form:input path="id"></form:input><form:errors path="id"></form:errors>

3、在控制器类中添加一个显示jsp的处理方法,一定要传入一个空的Person对象到Model中。
4、在form标签上一定要加上modelAttribute标签,modelAttribute的值必须是第三步控制器中传入进来的。

1、Person实体类

@NotNull
@Min(1)
private Integer id;

@NotEmpty
private String userName;

@Past(message = "输入的日期不能大于当前日期。")
private Date birthday;
private Double balance;

@Range(min = 2000,max = 10000)
private Double salary;

@Range(min = 0,max = 1)
private Double taskCount;
private String[] hobbies;

2、控制器类

@GetMapping("/person/add")
public String addView(Person person){
    return "/user/addPerson";
}

@RequestMapping("/formAddPerson")
public String formAdd(@Valid Person person, BindingResult result, Model model){
    /*
     将错误信息取出来,输出到jsp页面
     */
    // 判断当前是否出现了错误
    if(result.hasErrors()){
        return "user/addPerson";
    }
    System.out.println(person);
    return "showPerson";
}

3、跳转之前的页面

<h1>添加form用户</h1>
<form:form action="${pageContext.request.contextPath}/formAddPerson" method="post" modelAttribute="person">
    <p>
        id:<form:input path="id"></form:input><form:errors path="id"></form:errors>
    </p>
    <p>
        userName:<form:input path="userName"></form:input><form:errors path="userName"></form:errors>
    </p>
    <p>
        birthday:<form:input path="birthday"></form:input><form:errors path="birthday"></form:errors>
    </p>
    <p>
        balance:<form:input path="balance"></form:input><form:errors path="balance"></form:errors>
    </p>
    <p>
        salary:<form:input path="salary"></form:input><form:errors path="salary"></form:errors>
    </p>
    <p>
        taskCount:<form:input path="taskCount"></form:input><form:errors path="taskCount"></form:errors>
    </p>
    <p>
        hobbies:
        <form:checkbox path="hobbies" value="唱歌"></form:checkbox>
        <form:label path="hobbies">唱歌</form:label>
        <form:checkbox path="hobbies" value="跳舞"></form:checkbox>
        <form:label path="hobbies">跳舞</form:label>
    </p>
    <p>
        <input type="submit" value="提交"/>
    </p>
</form:form>

4、跳转之后的页面

<body>
    <p>
        id:${person.id} <br/>
    </p>
    <p>
        userName:${person.userName} <br/>
    </p>
    <p>
        birthday: <spring:eval expression="person.birthday"></spring:eval><br/>
    </p>
    <p>
        balance:<spring:eval expression="person.balance"></spring:eval> <br/>
    </p>
    <p>
        salary:<spring:eval expression="person.salary"></spring:eval> <br/>
    </p>
    <p>
        taskCount:<spring:eval expression="person.taskCount"></spring:eval> <br/>
    </p>
    <p>
        hobbies: <spring:eval expression="person.hobbies"></spring:eval> <br/>
    </p>
</body>

特点:

1、支持全部http请求,比如method=“put” put\delete等提交方式,当服务器在编译form表单的时候,如果我们写了put或者delete,就会自动给我们加入隐藏的标签行。
2、数据自动回显:需要使用modelAttribute指定数据的对象。
3、使用path双向绑定属性。
4、Select、checkboxs、radiobottons、都可以使用Items指定数据源,可以是list(当List的泛型是JavaBean的时候,需要指定itemValue和itemLable),map(不需要指定itemValue和itemLable)。
5、初始化需要用数组或者List。
List和Map举例:

// 控制器
/*List list = Arrays.asList("唱歌","跳舞","打篮球");
model.addAttribute("list",list);*/

Map<String,String> map = new HashMap<String, String>();
map.put("1","唱歌");
map.put("2","跳舞");
map.put("3","打乒乓球");
model.addAttribute("list",map);

// jsp文件
<form:checkboxes path="hobbies" items="${list}"></form:checkboxes>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值