Reputation: 437
I have a very simple Spring rest controller as follows:
@RequestMapping("/management")
@RestController
public class ManagementController {
@Autowired
private ManagementService managementService;
@ExceptionHandler(DuplicateEntityException.class)
@ResponseStatus(code = HttpStatus.CONFLICT)
public ErrorDetail handleDuplicateEntityException(DuplicateEntityException ex) {
return new ErrorDetail(ex.getMessage(), HttpStatus.CONFLICT.value());
}
@RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseStatus(code = HttpStatus.CREATED)
public User createUser(@RequestBody User user) {
return managementService.createUser(user);
}
}
and the ErrorDetail class...
@XmlRootElement(name = "error")
@XmlAccessorType(XmlAccessType.FIELD)
public class ErrorDetail {
@XmlElement(name = "message")
private String message;
@XmlAttribute(name = "status")
private int status;
public ErrorDetail(String message, int status) {
super();
this.message = message;
this.status = status;
}
public String getMessage() {
return message;
}
public int getStatus() {
return status;
}
public void setMessage(String message) {
this.message = message;
}
public void setStatus(int status) {
this.status = status;
}
}
and the custom exception, AAAException extends RuntimeException.
public class DuplicateEntityException extends AAAException {
private static final long serialVersionUID = 4223773548694193141L;
public DuplicateEntityException(String message) {
super(message);
}
public DuplicateEntityException(String message, Throwable cause) {
super(message, cause);
}
}
However the @ExceptionHandler will not marshall the ErrorDetail object I just get a 500, I can return a String from this method and it works. I'm sending application/xml which is being correctly unmarshalled and marshalled via createUser method and I can't understand why the same isn't working for the @ExceptionHandler.
I'm using Spring 4.2.6.
Any help would be greatly appreciated.
Upvotes: 1
Views: 1601
Reputation: 437
Well I'm embarrassed to say after debugging through the code the issue turns out to be a missing default constructor on the ErrorDetail class :-(
Upvotes: 0
Reputation: 2989
it seems that you have added the exception handler
method within the controller
because of that it will be triggered if you get an exception
from that controller
itself. use seperate class for exception handling ex:
@ControllerAdvice
public class GlobalExceptionController {
@ExceptionHandler(DuplicateEntityException.class)
@ResponseBody
public ErrorDetail handleDuplicateEntityException(DuplicateEntityException ex) {
ExceptionRepresentation body = new ExceptionRepresentation(ex.getMessage());
HttpStatus responseStatus = HttpStatus.CONFLICT;
return new ResponseEntity<ExceptionRepresentation>(body,responseStatus);
}
here using @ControllerAdvice
will apply exception
handling for every controller.
and the most important part is your methods should throw exceptions inorder for @ExceptionHandler
to work change your method signature.
public User createUser(@RequestBody User user) throw DuplicateEntityException{
throw new DuplicateEntityException();
}
Upvotes: 1