I have a controller advice class, but I can't seem to get it to return XML, even though I've used the @RequestMapping
annotation. Here's a stripped-down example.
@RestControllerAdvice
public class ControllerAdvice {
@ExceptionHandler(Exception.class)
@RequestMapping(produces = MediaType.APPLICATION_XML_VALUE)
public PriceAvailabilityResponse handleControllerErrorXML(final Exception e) {
e.printStackTrace();
System.out.println("Exception Handler functional");
PriceAvailabilityResponse priceAvailabilityResponse = new PriceAvailabilityResponse();
priceAvailabilityResponse.setStatusMessage("Server Error");
priceAvailabilityResponse.setStatusCode(99);
return priceAvailabilityResponse;
}
}
Note how @RequestMapping(produces = MediaType.APPLICATION_XML_VALUE)
works in rest controllers to control how the response is formed.
And here's an example of what the PriceAvailabilityResponse
could be from the aforementioned block of code.
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Getter
@Setter
public class PriceAvailabilityResponse {
@JacksonXmlProperty(isAttribute = true, localName = "StatusCode")
@JsonProperty(value = "StatusCode", required = false)
private int statusCode = 0;
@JacksonXmlProperty(isAttribute = true, localName = "StatusMessage")
@JsonProperty(value = "StatusMessage", required = false)
private String statusMessage;
}
And below is an example rest controller method to throw the error
@RequestMapping(value = "/error_test", produces = MediaType.APPLICATION_XML_VALUE)
public PriceAvailabilityResponse getPriceResponse() throws Exception{
int x = 1/0;
return null;
}
I've written the model for this code to return both JSON and XML depending on which endpoint is hitting the microservice, that is absolutely imperative.
Unfortunately, when I hit the /error_test
path, my response always comes in JSON.
How could I force the response to be XML? Thanks so much for your time.
Below approach should solve your problem
@RestController
public class TestController {
@GetMapping(value = "/throw-exception", produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity throwException(){
throw new CustomException("My Exception");
}
}
Return response entity from exception handler and specify the media type with it.
@ControllerAdvice
public class GlobalErrorHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = {CustomException.class})
protected ResponseEntity handleInvalidDataException(
RuntimeException ex, WebRequest request) {
PriceAvailabilityResponse priceAvailabilityResponse = new
PriceAvailabilityResponse();
priceAvailabilityResponse.setStatusMessage("Server Error");
priceAvailabilityResponse.setStatusCode(99);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_XML)
.body(priceAvailabilityResponse);
}
Include jackson-dataformat-xml dependency if you don't have one
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.8</version>
</dependency>