2010-05-01 5 views
19

Ich habe einen Controller, der JSON zurückgibt. Es nimmt eine Form an, die sich über Federnotizen validiert. Ich kann FieldError-Liste von BindingResult abrufen, aber sie enthalten nicht den Text, den eine JSP in dem Tag anzeigen würde. Wie kann ich den Fehlertext in JSON zurücksenden lassen?So erhalten Sie Fehlertext im Controller von 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; 
    } 

} 

JSONREsponse Klasse ist nur ein 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... 
} 

Aufruf BindingResult.getAllErrors() gibt ein Array von FieldError Objekte, aber es hat nicht die tatsächlichen Fehler.

Antwort

29

Haftungsausschluss: Ich benutze immer noch nicht Frühling-MVC 3.0

Aber ich denke, dass der gleiche Ansatz von Spring verwendet 2.5 kann Ihre Bedürfnisse

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()); 
    } 
} 

fullfil hoffe, dass ich es für Sie nützlich sein können

UPDATE

Wenn Sie die Nachricht von Ihrem Ressourcenpaket zur Verfügung gestellt werden wollen, müssen Sie eine Registe rot Message Instanz

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

spritzen Sie Ihre Message Instanz in Ihrer Ansicht

@Autowired 
private MessageSource messageSource; 

Und um Ihre Nachricht (Es Muss Message genannt werden), gehen Sie wie folgt

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); 
    } 
} 

Ihre Der Validator sollte wie folgt aussehen:

+1

Sagen wir, ich habe folgende in ValidationMessages.pr operties: "answerform.questionId.invalid = Ungültige Frage-ID: {0}." fieldError.getCode() wird "answerform.questionId.invalid" zurückgeben, ich suche den Fehler selbst, nicht den Code, zB: "Ungültige Frage ID: 123" – Mike

+0

@Mike Siehe ** Update **! –

+0

@Mike Wenn meine Antwort Ihre Bedürfnisse erfüllt, wäre es möglich, dass Sie es als akzeptiert markieren ??? –

19

ich dieses Problem vor kurzem traf und fand einen einfacheren Weg (vielleicht ist es die Unterstützung von Spring 3)

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

Es gibt keine Notwendigkeit zu ändern/die Nachrichtenquelle hinzufügen.

+0

@ J. Wincewicz: Tut mir leid, Ihren Bearbeitungsvorschlag nicht zu genehmigen. Der obige Code I was ich im Frühjahr 3 getestet (und ausgeführt habe). Ihr Code schlägt vor, eine neue Methode zu verwenden, bei der ich mir nicht 100% sicher bin, dass es mit dieser alten Version von Spring funktionieren wird. Sie können es jedoch als separate Antwort oder Kommentare zu diesem Post veröffentlichen. –

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)); 
} 

HINWEIS: Aufruf Errors.getDefaultMessage() nicht unbedingt die gleiche Nachricht zurück, die erzeugt wird, aus dem Code + Argumente. Die Standardnachricht ist ein separater Wert, der beim Aufrufen der Methode Errors.rejectValue() definiert wird.Siehe Errors.rejectValue() API Here

3

Mit 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()); 
} 

Controller:

@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

Vielleicht wäre eine etwas detailliertere Erklärung hilfreich. – Nubok