spring validation 源碼分析

http://www.blogjava.net/syniii/archive/2010/11/24/338906.html 

aware解釋

aware 

EnvironmentCapable


EnvironmentAware



spring-core

spring-bean

spring-web

spring-webmvc


在雲盒項目中,後臺管理表單數據校驗目前都是硬編碼,同時這種硬編碼跟業務邏輯的處理混在一起,也違背編碼單一職責原則,有沒有好點辦法方法將這數據校驗與業務處理分離開呢?我研究了一下spring mvc ,確實有個叫做spring validation,這個還有規範,Bean Validation 1.0(JSR-303)最新都1.1了,hibernate validation 對它進行了很好實現。下面介紹一下怎麼使用以及實現原理

1.怎麼應用

導入如下兩個包

配置validation相關spring bean

web 層controller 怎麼配置

velocity

2.代碼實現

private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,

NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {


Class[] paramTypes = handlerMethod.getParameterTypes();

Object[] args = new Object[paramTypes.length];


for (int i = 0; i < args.length; i++) {

MethodParameter methodParam = new MethodParameter(handlerMethod, i);

methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);

GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());

String paramName = null;

String headerName = null;

boolean requestBodyFound = false;

String cookieName = null;

String pathVarName = null;

String attrName = null;

boolean required = false;

String defaultValue = null;

boolean validate = false;

Object[] validationHints = null;

int annotationsFound = 0;

Annotation[] paramAnns = methodParam.getParameterAnnotations();


for (Annotation paramAnn : paramAnns) {

if (RequestParam.class.isInstance(paramAnn)) {

RequestParam requestParam = (RequestParam) paramAnn;

paramName = requestParam.value();

required = requestParam.required();

defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());

annotationsFound++;

}

else if (RequestHeader.class.isInstance(paramAnn)) {

RequestHeader requestHeader = (RequestHeader) paramAnn;

headerName = requestHeader.value();

required = requestHeader.required();

defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());

annotationsFound++;

}

else if (RequestBody.class.isInstance(paramAnn)) {

requestBodyFound = true;

annotationsFound++;

}

else if (CookieValue.class.isInstance(paramAnn)) {

CookieValue cookieValue = (CookieValue) paramAnn;

cookieName = cookieValue.value();

required = cookieValue.required();

defaultValue = parseDefaultValueAttribute(cookieValue.defaultValue());

annotationsFound++;

}

else if (PathVariable.class.isInstance(paramAnn)) {

PathVariable pathVar = (PathVariable) paramAnn;

pathVarName = pathVar.value();

annotationsFound++;

}

else if (ModelAttribute.class.isInstance(paramAnn)) {

ModelAttribute attr = (ModelAttribute) paramAnn;

attrName = attr.value();

annotationsFound++;

}

else if (Value.class.isInstance(paramAnn)) {

defaultValue = ((Value) paramAnn).value();

}

else if (paramAnn.annotationType().getSimpleName().startsWith("Valid")) {

validate = true;

Object value = AnnotationUtils.getValue(paramAnn);

validationHints = (value instanceof Object[] ? (Object[]) value : new Object[] {value});

}

}


if (annotationsFound > 1) {

throw new IllegalStateException("Handler parameter annotations are exclusive choices - " +

"do not specify more than one such annotation on the same parameter: " + handlerMethod);

}


if (annotationsFound == 0) {

Object argValue = resolveCommonArgument(methodParam, webRequest);

if (argValue != WebArgumentResolver.UNRESOLVED) {

args[i] = argValue;

}

else if (defaultValue != null) {

args[i] = resolveDefaultValue(defaultValue);

}

else {

Class<?> paramType = methodParam.getParameterType();

if (Model.class.isAssignableFrom(paramType) || Map.class.isAssignableFrom(paramType)) {

if (!paramType.isAssignableFrom(implicitModel.getClass())) {

throw new IllegalStateException("Argument [" + paramType.getSimpleName() + "] is of type " +

"Model or Map but is not assignable from the actual model. You may need to switch " +

"newer MVC infrastructure classes to use this argument.");

}

args[i] = implicitModel;

}

else if (SessionStatus.class.isAssignableFrom(paramType)) {

args[i] = this.sessionStatus;

}

else if (HttpEntity.class.isAssignableFrom(paramType)) {

args[i] = resolveHttpEntityRequest(methodParam, webRequest);

}

else if (Errors.class.isAssignableFrom(paramType)) {

throw new IllegalStateException("Errors/BindingResult argument declared " +

"without preceding model attribute. Check your handler method signature!");

}

else if (BeanUtils.isSimpleProperty(paramType)) {

paramName = "";

}

else {

attrName = "";

}

}

}


if (paramName != null) {

args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);

}

else if (headerName != null) {

args[i] = resolveRequestHeader(headerName, required, defaultValue, methodParam, webRequest, handler);

}

else if (requestBodyFound) {

args[i] = resolveRequestBody(methodParam, webRequest, handler);

}

else if (cookieName != null) {

args[i] = resolveCookieValue(cookieName, required, defaultValue, methodParam, webRequest, handler);

}

else if (pathVarName != null) {

args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);

}

else if (attrName != null) {

WebDataBinder binder =

resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);

boolean assignBindingResult = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));

if (binder.getTarget() != null) {

doBind(binder, webRequest, validate, validationHints, !assignBindingResult);

}

args[i] = binder.getTarget();

if (assignBindingResult) {

args[i + 1] = binder.getBindingResult();

i++;

}

implicitModel.putAll(binder.getBindingResult().getModel());

}

}


return args;

}


private void doBind(WebDataBinder binder, NativeWebRequest webRequest, boolean validate,

Object[] validationHints, boolean failOnErrors) throws Exception {


doBind(binder, webRequest);

if (validate) {

binder.validate(validationHints);

}

if (failOnErrors && binder.getBindingResult().hasErrors()) {

throw new BindException(binder.getBindingResult());

}

}



public void validate(Object... validationHints) {

for (Validator validator : getValidators()) {

if (!ObjectUtils.isEmpty(validationHints) && validator instanceof SmartValidator) {

((SmartValidator) validator).validate(getTarget(), getBindingResult(), validationHints);

}

else if (validator != null) {

validator.validate(getTarget(), getBindingResult());

}

}

}

















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章