Mit Spring Boot bin ich mir nicht ganz sicher, warum das notwendig war (ich habe das /error
-Fallback erhalten, obwohl @ResponseBody
auf einem @ExceptionHandler
definiert war), aber das Folgende hat für sich allein nicht funktioniert:
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ErrorMessage handleIllegalArguments(HttpServletRequest httpServletRequest, IllegalArgumentException e) {
log.error("Ungültige Argumente erhalten.", e);
ErrorMessage errorMessage = new ErrorMessage();
errorMessage.code = 400;
errorMessage.message = e.getMessage();
return errorMessage;
}
Es hat immer noch eine Ausnahme ausgelöst, anscheinend weil keine produzierbaren Medientypen als Anforderungsattribut definiert wurden:
// AbstractMessageConverterMethodProcessor
@SuppressWarnings("unchecked")
protected void writeWithMessageConverters(T value, MethodParameter returnType,
ServletServerHttpRequest inputMessage, ServletServerHttpResponse outputMessage)
throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
Class valueType = getReturnValueType(value, returnType);
Type declaredType = getGenericType(returnType);
HttpServletRequest request = inputMessage.getServletRequest();
List requestedMediaTypes = getAcceptableMediaTypes(request);
List producibleMediaTypes = getProducibleMediaTypes(request, valueType, declaredType);
if (value != null && producibleMediaTypes.isEmpty()) {
throw new IllegalArgumentException("Kein Konverter gefunden für den Rückgabewert vom Typ: " + valueType); // <-- wirft
}
// ....
@SuppressWarnings("unchecked")
protected List getProducibleMediaTypes(HttpServletRequest request, Class valueClass, Type declaredType) {
Set mediaTypes = (Set) request.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
if (!CollectionUtils.isEmpty(mediaTypes)) {
return new ArrayList(mediaTypes);
Also habe ich sie hinzugefügt.
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ErrorMessage handleIllegalArguments(HttpServletRequest httpServletRequest, IllegalArgumentException e) {
Set mediaTypes = new HashSet<>();
mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
httpServletRequest.setAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes);
log.error("Ungültige Argumente erhalten.", e);
ErrorMessage errorMessage = new ErrorMessage();
errorMessage.code = 400;
errorMessage.message = e.getMessage();
return errorMessage;
}
Und das hat mich dazu gebracht, einen "unterstützten kompatiblen Medientyp" zu haben, aber dann hat es immer noch nicht funktioniert, weil mein ErrorMessage
fehlerhaft war:
public class ErrorMessage {
int code;
String message;
}
JacksonMapper hat es nicht als "konvertierbar" behandelt, also musste ich Getter/Setter hinzufügen, und ich habe auch die @JsonProperty
-Annotation hinzugefügt
public class ErrorMessage {
@JsonProperty("code")
private int code;
@JsonProperty("message")
private String message;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Dann habe ich meine Nachricht wie beabsichtigt erhalten
{"code":400,"message":"Ein \"url\"-Parameter muss definiert sein."}