So I have a @RestController and I want to return and validate XML based on a schema for a front-end application in order to display them in an editor. I want the errors to be in json format in order to handle and display them with js.
@RestController public class UserController { @RequestMapping(value = "/test", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE) public ResponseEntity<String> throwException( @RequestParam(value = "flag", defaultValue = "false") Boolean flag ) throws Exception { if (flag) { throw new Exception(); } else { return ResponseEntity.ok("<xml>hello</xml>"); } } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(Exception.class) @ResponseBody ServerError exceptionHandler(HttpServletRequest req, Exception ex) { return new ServerError(req.getRequestURL().toString(),ex); } }
The ServerError I want to return in JSON format :
public class ServerError { public final String url; public final String error; public ServerError(String url, Exception ex) { this.url = url; this.error = ex.getMessage(); } public String getUrl() { return url; } public String getError() { return error; } }
So the <xml>hello</xml>
is returned just fine but when I set the flag to true
I get
ERROR 2017-10-18 12:56:53,189 [http-nio-0.0.0.0-8080-exec-2] org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: eu.openminted.registry.core.exception.ServerError eu.openminted.registry.service.UserController.malformedExeption(javax.servlet.http.HttpServletRequest,java.lang.Exception) org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
Also, setting the produces
to both XML and JSON yields the same result
@RequestMapping(value = "/test", method = RequestMethod.GET, produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_UTF8_VALUE})
Advertisement
Answer
I have managed to solve this by removing the produces
from @RequestMapping
and specifying with ResponseEntity
the type I want to return
@RequestMapping(value = "/test", method = RequestMethod.GET) public ResponseEntity<String> throwException( @RequestParam(value = "flag", defaultValue = "false") Boolean flag ) throws Exception { if (flag) { throw new Exception(); } else { ResponseEntity response = ResponseEntity.ok(). contentType(MediaType.APPLICATION_XML). body("<xml>hello</xml>"); return response; } }
The problem with that solution is that all of the methods have an @annotation
with the type they produce and this doesn’t, breaking uniformity.