2010-05-01 13 views
19

Ho un controller che restituisce JSON. Prende un modulo, che si convalida tramite annotazioni a molla. Posso ottenere l'elenco FieldError da BindingResult, ma non contengono il testo che un JSP dovrebbe visualizzare nel tag. Come posso ottenere il testo di errore da inviare in JSON?Come ottenere il testo di errore nel controller da 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; 
    } 

} 

classe JSONREsponse è solo un 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() restituisce un array di oggetti FieldError, ma non ha gli errori attuali.

risposta

29

Disclaimer: ancora non utilizzare Primavera-MVC 3.0

ma penso che lo stesso approccio utilizzato entro la primavera del 2,5 grado di esaudire le vostre esigenze

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

Spero che possa essere utile a voi

UPDATE

Se si desidera ottenere il messaggio fornito dal pacchetto di risorse, è necessario un Registe esempio rosso MessageSource (E must essere chiamato MessageSource)

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

Iniettare l'istanza MessageSource all'interno della vostra vista

@Autowired 
private MessageSource messageSource; 

e per ottenere il vostro messaggio, procedere come segue

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

tuo Il validatore dovrebbe apparire come

/** 
    * 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

Diciamo che ho seguito in ValidationMessages.pr operties: "answerform.questionId.invalid = ID domanda non valido: {0}." fieldError.getCode() restituirà "answerform.questionId.invalid", sto cercando l'errore stesso, non il codice, ad esempio: "ID domanda non valida: 123" – Mike

+0

@Mike Vedere ** Aggiornamento **! –

+0

@Mike Se la mia risposta soddisfa pienamente le tue esigenze, sarebbe possibile contrassegnarla come accettata ??? –

19

ho incontrato questo problema da poco, e hanno trovato un modo più semplice (forse è il supporto di Primavera 3)

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

Non c'è bisogno di cambiare/aggiungere la fonte del messaggio.

+0

@ J.Wincewicz: mi dispiace per non aver approvato il tuo suggerimento di modifica. Il codice precedente I quello che ho testato (e in esecuzione) in primavera 3. Il tuo codice suggerisce di utilizzare un nuovo metodo, che non sono sicuro al 100% che funzioni con questa vecchia versione di Spring. Puoi postarlo come una risposta separata o commenti su questo post, però. –

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

NOTA: Calling Errors.getDefaultMessage() non necessariamente tornare lo stesso messaggio che viene generato dal codice + args. DefaultMessage è un valore separato definito quando si chiama il metodo Errors.rejectValue().Vedere Errors.rejectValue() API Here

3

con 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

Forse una spiegazione un po 'più dettagliata sarebbe utile. – Nubok

Problemi correlati