2013-08-28 54 views
0

我有一個帶有HTML/endoUI UI的SpringMVC 3.2服務,我無法返回消息。看起來,我填充的RequestAttributes對Javascript不可見。我所看到的SpringMVC錯誤處理的所有示例都使用html或jsp重定向。使用JavaScript UI的SpringMVC錯誤處理

這裏有一個例子:

@Controller 
@RequestMapping("/officeSignUp") 
public class OfficeSignUpController 
.. 
@RequestMapping(value = "/stepOne", method = RequestMethod.POST) 
@ResponseBody 
public String officeCreationStepOne(@Valid @ModelAttribute("officeSetup") OfficeSetup officeSetup, 
     BindingResult result, Model model, RedirectAttributes attributes) { 
    String results; 

    results = newOfficeValidator.validateStepOne(officeSetup, result); 

    NewCustomerSignup newCustSignup = newOfficeValidator.validateNewOwner(officeSetup); 

    model.addAttribute(newCustomerSignupRepository.save(newCustSignup)); 

    return results; 

} 

我的驗證是:

@Component 公共類NewOfficeValidator {

public String validateStepOne(OfficeSetup officeSetup, BindingResult result) { 

List<String> errors = new ArrayList<String>(); 
if (result.hasErrors()) { 
    for (ObjectError error : result.getAllErrors()) { 
     errors.add(error.getDefaultMessage()); 
    } 
    errors.add("redirect: " + VIEW_STEP_ONE); 
      // RuntimeException with a list of strings in it 
    throw new OfficeSetupException(errors, "Validation in StepOne"); 
    } 


    return VIEW_STEP_TWO; 
} 

在我BaseController我捕捉到了異常,檢索錯誤消息並使用它們:

@ExceptionHandler 
@ResponseStatus(HttpStatus.BAD_REQUEST) 
@ResponseBody 
public ErrorMessage handleOfficeSetupException(OfficeSetupException ex) { 

    List<String> errors = ex.getErrors(); 
    StringBuilder sb = new StringBuilder(); 
    for (String error : errors) { 
     sb.append(error); 
    } 
     // this is just a bean with a list of Strings 
    return new ErrorMessage(errors); 
} 

當一個異常被拋出,而不是一個JSON或字符串的反應,我得到它包含了tomcat HTML郵件:

<h1>HTTP Status 400 - Received OfficeSetupException </h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>Received OfficeSetupException </u></p><p><b>description</b> <u>The request sent by the client was syntactically incorrect (Received OfficeSetupException).</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.27</h3></body></html> 

,然後在JavaScript:

if(stepString == "Step 2"){ click on step 2 
     if(viewModelStepOne.validateStepOne(s) == true){ client side validation 
      viewModelStepOne.saveStepOne(s);if above validation passes, send request to server, 
     if(serverValidationFailed){if server returns error, do not move to step 2 
      s.preventDefault(); 
     }else{ move to step 
      this.disable(this.tabGroup.children("li").eq(2),true); 
      this.enable(this.tabGroup.children("li").eq(3),true); 
     } 
    }else{ s.preventDefault(); 
    } 
} 

所以,最後我問題是:從spring mvc到javascript前端返回驗證或其他錯誤消息的最佳方式是什麼?我想爲我的回覆使用JSON,所以我希望ErrorMessage能夠被返回。

+0

我注意到您在使用@ResponseBody註解的處理程序方法中使用model.addAttribute(...)。這是爲什麼? (模型用於訪問數據,但您沒有使用視圖)。 –

回答

1

在我的項目中,我按照你所描述的做 - 拋出一個異常,並用@ExceptionHandler來捕獲它。但是你不需要只返回一個字符串消息。創建你自己的異常類,它可以將Map或錯誤列表作爲參數(或任何你想用作錯誤模型的東西)。發生錯誤時,將錯誤填充到您的自定義執行選項(讓我們稱之爲RequestException),然後拋出它。錯誤將被存儲在您的exeception實例中。在@ExceptionHandler中,您的RequestException從異常對象中獲取錯誤,然後以一種方便的方式返回到前端。

+0

我用@ExceptionHandler更新了我的文章,並在UI上收到了實際的錯誤消息。出於某種原因,實際的異常似乎是從那裏拋出,不應該是這種情況 – sonoerin

+0

你可以驗證handleOfficeSetupException確實是在validateStepOne中拋出異常之後調用和執行的嗎?另外,OfficeSignUpController類是否擴展了BaseController? (我認爲是的,但在發佈的代碼中是不可見的) –

+0

是的,我可以一步一步看到BaseController處理異常,然後解析錯誤並返回ErrorMessage。 UI收到400(通過FireBug確認)和Tomcat錯誤。 – sonoerin

0

我想我通過在我的例外中添加「@JsonAutoDetect」來解決它。我正在使用Java Config,因此以下內容似乎將處理HTTP響應代碼並返回JSON響應。

@JsonAutoDetect(fieldVisibility = Visibility.DEFAULT, getterVisibility = Visibility.DEFAULT, isGetterVisibility = Visibility.DEFAULT) 
public class OfficeSetupException extends RuntimeException { 

    private List<String> errors; 

    private static final long serialVersionUID = -1L; 

    public OfficeSetupException(List<String> errors, String message) { 
     super(message); 
     this.errors = errors; 
    } 

    public List<String> getErrors() { 
     return errors; 
    } 

}