2010-05-01 17 views
19

Tôi có một bộ điều khiển trả về JSON. Nó có một hình thức, xác nhận chính nó thông qua các chú thích mùa xuân. Tôi có thể lấy danh sách FieldError từ BindingResult, nhưng chúng không chứa văn bản mà JSP sẽ hiển thị trong thẻ. Làm thế nào tôi có thể nhận được văn bản lỗi để gửi lại trong JSON?Cách lấy văn bản lỗi trong bộ điều khiển từ BindingResult

@RequestMapping(method = RequestMethod.POST) 
public 
@ResponseBody 
JSONResponse submit(@Valid AnswerForm answerForm, BindingResult result, Model model, HttpServletRequest request, HttpServletResponse response) { 

    if (result.hasErrors()) { 
     response.setStatus(HttpServletResponse.SC_BAD_REQUEST); 
     JSONResponse r = new JSONResponse(); 
     r.setStatus(JSONResponseStatus.ERROR); 
     //HOW DO I GET ERROR MESSAGES OUT OF BindingResult??? 
    } else { 
     JSONResponse r = new JSONResponse(); 
     r.setStatus(JSONResponseStatus.OK); 
     return r; 
    } 

} 

lớp JSONREsponse chỉ là một POJO

public class JSONResponse implements Serializable { 
    private JSONResponseStatus status; 
    private String error; 
    private Map<String,String> errors; 
    private Map<String,Object> data; 

...getters and setters... 
} 

Calling BindingResult.getAllErrors() trả về một mảng các đối tượng FieldError, nhưng nó không có lỗi thực tế.

Trả lời

29

Disclaimer: Tôi vẫn không sử dụng Spring MVC 3,0

Nhưng tôi nghĩ rằng phương pháp tương tự được sử dụng bởi mùa xuân 2.5 có thể đảm bảo thực nhu cầu của bạn

for (Object object : bindingResult.getAllErrors()) { 
    if(object instanceof FieldError) { 
     FieldError fieldError = (FieldError) object; 

     System.out.println(fieldError.getCode()); 
    } 

    if(object instanceof ObjectError) { 
     ObjectError objectError = (ObjectError) object; 

     System.out.println(objectError.getCode()); 
    } 
} 

Tôi hy vọng nó có thể hữu ích cho bạn

CẬP NHẬT

Nếu bạn muốn nhận được thông báo do gói tài nguyên của bạn cung cấp, bạn cần đăng ký Ví dụ màu đỏ messageSource (Nó phải được gọi messageSource)

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> 
    <property name="basenames" value="ValidationMessages"/> 
</bean> 

Tiêm dụ MessageSource của bạn bên trong Xem bạn

@Autowired 
private MessageSource messageSource; 

Và để nhận được tin nhắn của bạn, hãy làm như sau

for (Object object : bindingResult.getAllErrors()) { 
    if(object instanceof FieldError) { 
     FieldError fieldError = (FieldError) object; 

     /** 
      * Use null as second parameter if you do not use i18n (internationalization) 
      */ 

     String message = messageSource.getMessage(fieldError, null); 
    } 
} 

của bạn Trình xác thực sẽ trông giống như

/** 
    * Use null as fourth parameter if you do not want a default message 
    */ 
errors.rejectValue("<FIELD_NAME_GOES_HERE>", "answerform.questionId.invalid", new Object [] {"123"}, null); 
+1

Hãy nói rằng tôi đã sau trong ValidationMessages.pr operties: "answerform.questionId.invalid = Id câu hỏi không hợp lệ: {0}." fieldError.getCode() sẽ trả về "answerform.questionId.invalid", tôi đang tìm lỗi, không phải mã, ví dụ: "Id câu hỏi không hợp lệ: 123" – Mike

+0

@Mike See ** Update **! –

+0

@Mike Nếu câu trả lời của tôi fullfil nhu cầu của bạn, nó sẽ có thể bạn đánh dấu nó như được chấp nhận? –

19

tôi gặp vấn đề này thời gian gần đây, và tìm thấy một cách dễ dàng hơn (có lẽ đó là sự ủng hộ của mùa xuân 3)

List<FieldError> errors = bindingResult.getFieldErrors(); 
    for (FieldError error : errors) { 
     System.out.println (error.getObjectName() + " - " + error.getDefaultMessage()); 
    } 

Không cần phải thay đổi/thêm nguồn thông điệp.

+0

@ J.Wincewicz: xin lỗi vì không phê duyệt đề xuất chỉnh sửa của bạn. Mã trên tôi những gì tôi đã thử nghiệm (và chạy) trong mùa xuân 3. Mã của bạn cho thấy sử dụng một phương pháp mới, mà tôi không chắc chắn 100% rằng nó sẽ làm việc với phiên bản cũ của Spring này. Tuy nhiên, bạn có thể đăng nó dưới dạng câu trả lời hoặc nhận xét riêng về bài đăng này. –

1

BEAN XML:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> 
    <property name="basenames"> 
     <list> 
      <value>messages</value> 
     </list>    
    </property> 
</bean> 

<bean id="messageAccessor" class="org.springframework.context.support.MessageSourceAccessor"> 
    <constructor-arg index="0" ref="messageSource"/> 
</bean> 

JAVA:

for (FieldError error : errors.getFieldErrors()) { 
    logger.debug(messageAccessor.getMessage(error)); 
} 

LƯU Ý: Calling Errors.getDefaultMessage() sẽ không nhất thiết phải trở lại cùng một thông điệp được tạo từ mã + args. DefaultMessage là một giá trị riêng biệt được định nghĩa khi gọi phương thức Errors.rejectValue().Xem Errors.rejectValue() API Here

3

Với Java 8 Streams

bindingResult 
.getFieldErrors() 
.stream() 
.forEach(f -> System.out.println(f.getField() + ": " + f.getDefaultMessage())); 
1

WebMvcConfigurerAdapter:

@Bean(name = "messageSourceAccessor") 
public org.springframework.context.support.MessageSourceAccessor messageSourceAccessor() { 
    return new MessageSourceAccessor(messageSource()); 
} 

Bộ điều khiển:

@Autowired 
@Qualifier("messageSourceAccessor") 
private MessageSourceAccessor   messageSourceAccessor; 
... 

StringBuilder sb = new StringBuilder(); 
for (ObjectError error : result.getAllErrors()) { 
    if (error instanceof FieldError) { 
     FieldError fe = (FieldError) error; 
     sb.append(fe.getField()); 
     sb.append(": "); 
    } 
    sb.append(messageSourceAccessor.getMessage(error)); 
    sb.append("<br />"); 
} 
+0

Có lẽ một lời giải thích phần nào được giải thích nhiều hơn sẽ hữu ích. – Nubok

Các vấn đề liên quan