2012-11-08 8 views
5

mio controller dispone di metodi che producono JSON o HTML a seconda della loro @RequestMapping (produce = "", consuma = "") le annotazioni. Tuttavia, quando si tratta di gestire le eccezioni in modo generico, sto affrontando problemi.Utilizzando @ExceptionHandler per servire JSON o la risposta HTML sulla base di @RequestMapping

@RequestMapping(method = POST) 
public String add(@Valid MyForm form, BindingResult result, Model model) { 
    if (result.hasErrors()) { 
     return "edit"; 
    } 

    throw new RuntimeException("Error adding"); 

    return "edit"; 
} 

@RequestMapping(method = POST, produces = "application/json", consumes = "application/json") 
@ResponseBody 
public Map<String, Object> addJSON(@RequestBody @Valid MyForm form, Model model) { 
    throw new RuntimeException("Error adding"); 
} 

Come scrivere @ExceptionHandler per i due metodi precedenti? Quello per quello non JSON dovrebbe aggiungere un attributo allo Model.

model.addAttribute("error", exception.getMessage()); 

Quello con JSON tipo di risposta deve restituire l'errore come un Map, per essere successivamente serializzato in JSON.

Ho provato sottostante ma molla non piace due diversi metodi @ExceptionHandler annotato dichiarate con lo stesso tipo di eccezione.

@ExceptionHandler(RuntimeException.class) 
@ResponseStatus(value = HttpStatus.BAD_REQUEST) 
@RequestMapping(produces = "application/json") 
@ResponseBody 
public Map<String, Object> handleExceptionAsJSON(RuntimeException exception) { 
    Map<String, Object> map = new HashMap<>(); 
    map.put("error", exception.getMessage()); 

    return map; 
} 

@ExceptionHandler(RuntimeException.class) 
public Map<String, Object> handleException(RuntimeException exception) { 
    Map<String, Object> map = new HashMap<>(); 
    map.put("error", exception.getMessage()); 

    return map; 
} 

risposta

0

Entrambi vostro argomento ExceptionHandler avere RuntimeException. Pertanto, nel tuo caso solo 1 exceptionhandler è onorato.

Non sono sicuro di cosa stia facendo. Ma immagino che scrivere il tuo exceptionresolver risolverebbe il tuo problema. L'ho già fatto. Ho creato il mio exceptionresolver dedicato solo per le richieste Ajax e poi lo ho incatenato con lo ExceptionHandlerExceptionResolver esistente.

+0

"ExceptionHandler è mappato rispetto all'argomento throwable, pertanto nel tuo caso solo un gestore di eccezioni è onorato." - quello non è vero! – adarshr

+0

Ho modificato la mia prima riga sopra. Se non mi credi, controlla ** linea 71 ** (metodo detectExceptionMappings) di "ExceptionHandlerMethodResolver'. Spring 3.2.x è il mio riferimento a proposito. – ramirezag

Problemi correlati