SpringMVC的数据验证(Spring验证)

SpringMVC的数据验证(Spring验证)

数据验证分为客户端验证和服务器端验证,客户端验证主要过滤正常用户的误操作,通过JavaScript代码实现;服务器端验证是整个应用阻止非法数据的最后防线,通过应用中编程实现。

用户的输入一般是随意的,为了保证数据的合法性,数据验证是所有web应用必须处理的问题,在SpringMVC中有两种方法可以验证输入数据,一种是利用Spring自带的验证框架,另一种是利用JSR303实现。

客户端验证:
在大多数情况下,使用JS进行客户端验证的步骤如下:
1-编写验证函数
2-在提交表单的时间中调用验证函数
3-根据验证函数判断是否提交表单
客户端验证可以过滤掉客户的误操作,是第一道防线,一般使用JS代码实现,但仅有客户端验证是不够的,攻击者还可以绕过客户端验证直接进行非法输入,这样可能会引起系统异常,为了确保数据的合法性,防止用户通过非正常手段提交错误信息,必须加上服务器验证。

服务器验证:
SpringMVC的Converter和Formatter在进行类型转换时是将输入数据转换成领域对象的属性值,一旦成功,服务器端验证就会介入,也就是说,在SpringMVC框中先进行数据类型转换,再进行服务器验证。服务器端验证对于系统的安全性,完整性,健壮性起到至关重要的作用,在SpringMVC框架中可以利用Spring自带的验证框架验证数据,也可以利用JSR 303实现数据验证。

Spring验证器
Validator接口:
创建自定义Spring验证器需要实现Validator接口,该接口有两个接口方法:
1-supports返回true,验证器可以处理指定的Class,validate方法的功能是验证目标对象object,并将验证消息存入Errors对象。
2-往Errors对象存入错误消息的方法是reject或rejectValue。

ValidationUtils类:
ValidationUtils是一个工具类,该类中有几个方法可以帮助用户判定值是否为空。

编写一个实现Validator接口的验证器类GoodsValidator,验证要求如下:
1-商品名和商品详情不能为空
2-商品价格在0到100
3-创建日期不能在系统日期之后

1-在IDEA中创建web应用ch14-1,在WEB-INF下创建目录lib,在lib目录下导入SpringMVC相关jar包,因为需要使用JSTL标签显示数据,所以需要导入JSTL相关jar包。
在这里插入图片描述
2-创建数据输入页面,在WEB-INF目录下创建文件夹jsp,并在该文件夹下创建数据输入页面addGoods.jsp,代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
         pageEncoding="utf-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
</head>
<body>
<form:form modelAttribute = "goods" action = "${pageContext.request.contextPath}/goods/save" method = "post">
    <fieldset>
        <lengend>添加一个商品</lengend>
        <p>
            <label>商品名:</label>
            <form:input path = "gname"/>
        </p>
        <p>
            <label>商品详情:</label>
            <form:input path = "gdescription"/>
        </p>
        <p>
            <label>创建价格:</label>
            <form:input path = "gprice"/>
        </p>
        <p>
            <label>创建日期:</label>
            <form:input path = "gdate"/>(yyyy-MM-dd)
        </p>
        <p id = "buttons">
            <input id = "reset" type = "reset"/>
            <input id = "submit" type = "submit" value = "添加"/>
        </p>
    </fieldset>
    <!--取出所有验证错误-->
    <form:errors path = "gname"/>
    <form:errors path = "gdescription"/>
    <form:errors path = "gprice"/>
    <form:errors path = "gdate"/>

</form:form>
</body>
</html>

3-编写模型,在src目录下创建pojo包,在该包中定义领域模型类Goods,封装商品信息到该类,在该类中使用@dDateTimeFormate(pattern=“yyyy-MM-dd”)格式化创建日期。


import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;

/**
 * 将商品属性封装到Goods类
 */
public class Goods  {
    private String gname ;
    private String gdescription ;
    private double gprice ;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date gdate ; //格式化创建日期

    public String getGname() {
        return gname;
    }

    public void setGname(String gname) {
        this.gname = gname;
    }

    public String getGdescription() {
        return gdescription;
    }

    public void setGdescription(String gdescription) {
        this.gdescription = gdescription;
    }

    public double getGprice() {
        return gprice;
    }

    public void setGprice(double gprice) {
        this.gprice = gprice;
    }

    public Date getGdate() {
        return gdate;
    }

    public void setGdate(Date gdate) {
        this.gdate = gdate;
    }
}

4-编写验证类,在src目录下创建validator包,并在该包中编写实现Validator接口的验证器类GoodsValidator,使用@Component注解将GoodsValidator类声明为验证器组件。
创建自定义Spring验证器需要实现Validator接口,该接口有两个接口方法:
1-supports返回true,验证器可以处理指定的Class,validate方法的功能是验证目标对象object,并将验证消息存入Errors对象。
2-往Errors对象存入错误消息的方法是reject或rejectValue。

ValidationUtils类:
ValidationUtils是一个工具类,该类中有几个方法可以帮助用户判定值是否为空。


import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import pojo.Goods;

import java.util.Date;

@Component
public class GoodsValidator implements Validator {
    @Override
    public boolean supports(Class<?> aClass) {
        //要验证的model,返回值false则不验证,true的时候,处理指定类
        return Goods.class.isAssignableFrom(aClass);
    }

    @Override
    public void validate(Object object, Errors errors) {
        Goods goods = (Goods) object ; //object要验证的对象
        ValidationUtils.rejectIfEmpty(errors, "gname", "goods.gname.required");
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "gdescription", "goods.gdescription.required");
        if(goods.getGprice() < 0 || goods.getGprice() > 100){
            errors.rejectValue("gprice", "gprice.invalid") ;
        }
        Date goodsDate = goods.getGdate() ;
        //在系统时间之后
        if(goodsDate != null && goodsDate.after(new Date())){
            errors.rejectValue("gdate", "gdate.invalid") ;
        }
    }
}

5-编写错误消息属性文件,在WEB-INF目录下创建文件夹resource,并在该文件夹中编写属性文件error.properties
内容入下:

goods.gname.required=请输入商品名称
goods.gdescription.required=请输入商品详情
gprice.invalid=价格为0-100
gdate.invalid=创建日期不能在系统日期之后

6-在src目录下创建service包,在该包中创建GoodsService接口和GoodsServiceImpl实现类。
GoodsService接口:


import pojo.Goods;

import java.util.ArrayList;

public interface GoodsService {
    boolean save(Goods goods) ; //添加商品方法
    ArrayList <Goods> getGoods() ; //查询商品方法
}

GoodsServiceImpl实现类:

import org.springframework.stereotype.Service;
import pojo.Goods;

import java.util.ArrayList;
@Service
public class GoodsServiceImpl implements GoodsService {
    //使用静态集合变量goods模拟数据库添加和查询商品信息
    private static ArrayList<Goods> goods = new ArrayList<>() ;

    @Override
    public boolean save(Goods g) {
        goods.add(g) ;
        return true;
    }

    @Override
    public ArrayList<Goods> getGoods() {
        return goods;
    }
}

7-编写控制器类,在src目录下创建controller包,在该包中编写控制器类GoodsController,在该类中使用@Resource注入自定义验证器类。在该类中 包含了2个请求处理方法。

package controller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import pojo.Goods;
import service.GoodsService;

import javax.annotation.Resource;


//@Resource注解注入自定义验证器,另外控制器类中包含了两个处理请求的方法
@Controller
@RequestMapping("/goods")
public class GoodsController {
    //得到一个用来记录日志的对象,打印信息的时候能够标记打印哪个类的信息
    private static final Log logger = LogFactory.getLog(GoodsController.class) ;
    @Autowired
    private GoodsService goodsService ;
    @Resource
    private Validator validator ; //注入验证器对象
    @RequestMapping("/input")
    public String input(Model model){
        //如果model中没有goods属性,addGoods.jsp将会抛储异常,因为表单标签无法找到modelAttribute属性指定的form backing object
        model.addAttribute("goods", new Goods()) ;
        return "addGoods" ;
    }
    @RequestMapping("/save")
    public String save(@ModelAttribute Goods goods, BindingResult result, Model model){
        this.validator.validate(goods, result); //验证goods,当前错误信息放到result
        if(result.hasErrors()){
            return "addGoods" ;
        }
        goodsService.save(goods) ;
        logger.info("添加成功") ;
        model.addAttribute("goodsList", goodsService.getGoods()) ;
        return "goodsList" ;
    }
}

8-在web.xml中部署DispatcherServlet ,配置 CharacterEncodingFilter解决中文乱码问题。

<?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"
         id = "WebApp_ID" version="4.0">
    <!--部署DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <!--表示容器启动时加载的servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--任意的请求都通过DispatcherServlet-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置 CharacterEncodingFilter解决中文乱码问题-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <!-- 配置编码格式为UTF-8 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

9-在WEB-INF目录下创建SpingMVC的配置文件springmvc-servlet.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
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--使用扫描机制,扫描控制器类,s使得注解生效-->
    <context:component-scan base-package="controller"/>
    <context:component-scan base-package="service"/>
    <context:component-scan base-package="validator"/>
    <mvc:annotation-driven />

    <!--因为使用了日期格式化转换器,所以需要注册日期格式化转换器-->
    <bean id = "conversionService" class = "org.springframework.format.support.FormattingConversionServiceFactoryBean">
    </bean>
    <mvc:annotation-driven conversion-service="conversionService"/>
    <!--SpringMVC想从属性文件中获取错误信息,需要配置一个MessageSource Bean-->
    <bean id = "messageSource" class = "org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name = "basename" value="/WEB-INF/resource/error"/>
    </bean>

    <!--配置视图解析器-->
    <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" id = "internalResourceViewResolver">
        <!--前缀-->
        <property name = "prefix" value = "/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name = "suffix" value = ".jsp"/>
    </bean>

</beans>

10-创建视图显示页面,在WEB-INF目录下的jsp目录中创建数据显示页面goodsList.jsp核心代码如下:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/8/12
  Time: 9:03
  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>
<table>
    <tr>
        <td>商品名</td>
        <td>商品详情</td>
        <td>商品价格</td>
        <td>创建日期</td>
    </tr>
    <c:forEach items="${goodsList}" var = "goods">
        <tr>
            <td>${goods.gname}</td>
            <td>${goods.gdescription}</td>
            <td>${goods.gprice}</td>
            <td>${goods.gdate}</td>
        </tr>
    </c:forEach>
</table>
</body>
</html>

11-发布该应用到tomcat,运行tomcat,然后通过地址:http://localhost:8080/ch14_1_war_exploded/goods/input
访问

验证商品名和商品详情为空:
在这里插入图片描述
验证价格不在设定范围内:
在这里插入图片描述
验证日期在系统日期之后:
在这里插入图片描述
验证全部添加正确:
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring MVC是一种基于MVC设计模式的轻量级Java框架,而Spring Security是一个专门用于身份验证和授权的安全框架。将Spring MVC项目集成Spring Security可以为项目提供更强大的安全性。 在Spring MVC项目中集成Spring Security的步骤如下: 1. 添加Spring Security依赖:在项目的pom.xml文件中添加Spring Security的依赖项,以便在项目中使用Spring Security的功能。 2. 配置Spring Security:创建一个SecurityConfig类,用于配置Spring Security的相关设置。可以在其中配置用户认证方式、权限管理和安全规则等。 3. 自定义用户认证:可以实现UserDetailsService接口,并重写loadUserByUsername方法来提供自定义的用户认证逻辑。也可以使用自定义的AuthenticationProvider来验证用户的身份。 4. 配置安全规则:可以通过配置AntMatchers来定义不同URL路径的访问权限。可以设置哪些角色或权限可以访问某个URL路径。 5. 配置登录和注销页面:创建登录和注销的控制器,并配置登录表单的提交地址和注销地址。可以为登录页面自定义视图,并对登录请求进行处理。 6. 使用安全注解:可以在控制器或方法上使用Spring Security提供的安全注解,如@PreAuthorize和@Secured,来对方法或URL进行细粒度的授权。 7. 使用Spring Security的标签库:可以使用相应的标签库来在JSP页面中展示用户信息、权限信息等。也可以通过标签来控制页面上的内容是否展示。 通过以上步骤,就可以在Spring MVC项目中成功集成Spring Security。集成后,项目将具备强大的身份验证和授权功能,能够有效保护项目的安全性,并对不同用户或角色进行权限控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值