Input类中常用的验证方式
Deolin一般将Input类对象作为POST请求方法的参数,
Input类的域与前端的数据结构一一对应,由于后端不应该相信前端传过来的任何数据,
所以前端的数据对象先绑定到Input对象中,通过JSR303做一次数据校验。
Input类的所有域,类型都是String,
1、不相信前端传来的数据,所以不用诸如Integer,java.util.Date类型的域。不然会出现ClassClassCastException。
2、String类型的域可以添加@Pattern的注解,保证Input对象的每一个域,都能顺利的转化为业务上对应的类型。
Input类
@NotBlank(message = "ID为空") @Size(max = 11, message = "ID长度超过11") @Pattern(regexp = "[0-9]+", message = "ID中有非数字") private String id;
业务上的整数类型
@NotBlank @Size(max = 500, message = "地址长度超过500字符") private String address;
长文本
@NotBlank @Size(max = 20) @Pattern(regexp = "[0-9\\-]+") private String telno;
手机号(这个正则可能不是最合适的)
@NotBlank @Pattern(regexp = "^true$|^false$", 不可用标识不是true且不是false) private String disableFlag;
逻辑值
@NotBlank @Pattern(regexp = "^\d{1,8}(\.\d{1,2})*$", message = "单价格式错误(整数长度超过8个数字,或小数长度超过2个数字,或不是数字格式)") private String price;
价格(最高价是99999999.99)
@NotBlank @Pattern (regexp = "^([01][0-9]|2[0-3]):([0-5][0-9])$", message = "格式不是HH:mm") private String breakfastTime;
时间(24小时制,长度不是5位 错误,全角冒号 错误)
控制器共用方法
package com.women.ordering.common; /** * 封装了控制器的共用方法<br> * * @author Deolin */ abstract public class Controller { private static final Logger LOG = LogManager.getLogger(Controller.class); /** * 检查前端提交的数据对象 * * @param checker JSR303检验结果的封装对象 * @throws InputException 存在任何的异常数据 */ protected void checkInput(BindingResult checker) { List<ObjectError> errors = checker.getAllErrors(); StringBuilder messages = new StringBuilder(400); if (errors.size() > 0) { for (ObjectError error : errors) { messages.append(error.getDefaultMessage()); } LOG.warn("有异常数据越过前端校验:" + messages); throw new InputException(messages.toString()); } } }
示例
/** * 前端 */ var jsonObj = {'id':'1aaa4', 'price':'10.999'}; $.ajax({ type : "post", url : "/test", dataType : "json", contentType : "application/json", data : JSON.stringify(jsonObj), success:function(back) { if (back.result) { alert("success"); } else { alert(back.message); } }, error:function(back) { alert('error'); } });
/** * 后端 */ @Controller public class TestController extends Controller { @RequestMapping(value = "test", method = RequestMethod.POST) @ResponseBody public RequestResult test(@RequestBody ProductInput input, BindingResult checker) { try { checkInput(checker); // TODO 业务代码 return "success"; } catch (Exception e) { return e.getMessage(); }; } }