2012-11-03 33 views
1

我有一個控制器,它接收包含請求XML的字符串作爲@RequestBody。Spring REST MVC:驗證傳入的XML(不使用表單)

@RequestMapping(method = RequestMethod.POST, value="/app-authorization") 
public Response getAppAuthorization(
     HttpServletResponse response, BindingResult results, 
     @RequestBody String body){ 
    log.info("Requested app-authorization through xml: \n" + body); 

    Source source = new StreamSource(new StringReader(body)); 
    RefreshTokenRequest req = (RefreshTokenRequest) jaxb2Mashaller.unmarshal(source); 

    validator.validate(req, results); 
    if(results.hasErrors()){ 
     log.info("DOESN'T WORK!"); 
     response.setStatus(500); 
     return null; 
    } 
    InternalMessage<Integer, Response> auth = authService.getRefreshToken(req); 
    response.setStatus(auth.getHttpStatus()); 
    return auth.getReponse(); 
} 

的AuthorizationValidator如下:

@Component("authenticationValidator") 
public class AuthenticationValidator implements Validator{ 

    public boolean supports(Class<?> clazz) { 
     return AuthorizationRequest.class.isAssignableFrom(clazz); 
    } 

    public void validate(Object target, Errors errors) { 
     errors.rejectValue("test", "there are some errors"); 

    } 
} 

我想知道是否有以這樣的方式來注入對象驗證到我的控制器的方式:

  1. @Autowired \ n驗證器驗證器;使我自動獲得對我的AuthenticationValidator的引用。每個控制器都鏈接到一個或多個驗證器,而不顯式指示它們的類。

回答

1

很多要手動做的事情可以由Spring MVC完全處理的,你應該能夠得到您的方法,這種結構:

@RequestMapping(method = RequestMethod.POST, value="/app-authorization") 
public Response getAppAuthorization(@Valid @RequestBody RefreshTokenRequest req, BindingResult results){ 

    if(results.hasErrors()){ 
     log.info("DOESN'T WORK!"); 
     response.setStatus(500); 
     return null; 
    } 
    InternalMessage<Integer, Response> auth = authService.getRefreshToken(req); 
    response.setStatus(auth.getHttpStatus()); 
    return auth.getReponse(); 
} 

與Spring MVC採取調用JAXB解組的護理和@Valid關於驗證類型的註釋。

現在註冊一個自定義驗證你的類型,你可以這樣做:

@InitBinder 
protected void initBinder(WebDataBinder binder) { 
    binder.setValidator(this.authenticationValidator); 
} 

如果你想設置全局,而不是爲特定的控制器,你可以創建自定義全球驗證,內部委託對於其他驗證,爲如:

public class CustomGlobalValidator implements Validator { 

    @Resource private List<Validator> validators; 

    @Override 
    public boolean supports(Class<?> clazz) { 
     for (Validator validator: validators){ 
      if (validator.supports(clazz)){ 
       return true; 
      } 
     } 
     return false; 
    } 

    @Override 
    public void validate(Object obj, Errors e) { 
     //find validator supporting class of obj, and delegate to it 

    } 
} 

並註冊這個全球性驗證:

<mvc:annotation-driven validator="globalValidator"/>