2013-08-28 50 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; 
    } 

}