gpt4 book ai didi

java - Spring MVC - 处理 HttpMediaTypeNotAcceptableException 时如何设置返回媒体类型?

转载 作者:行者123 更新时间:2023-12-01 04:52:21 33 4
gpt4 key购买 nike

我有一个 Spring 3.2 MVC REST 服务,它通过扩展 ResponseEntityExceptionHandler 来实现错误处理。这处理 standard Spring exceptions ,并将根据客户端的请求,以适当的 HTTP 状态和 XML 或 JSON 格式的自定义“错误”ResponseEntity 对象进行响应。这对于除 HttpMediaTypeNotAcceptableException 之外的所有标准异常都非常有效。

我遇到的这个异常的问题是,它首先抛出的原因是无法从请求中确定响应媒体类型(application/xml、application/json 等)。如果我尝试为此异常返回“错误”ResponseEntity 对象,它将失败,因为无法确定响应媒体类型(这就是首先处理此异常的原因)...并且基本上得到另一个 HttpMediaTypeNotAcceptableException 从我的 ExceptionHandler 中抛出。

我需要在处理 HttpMediaTypeNotAcceptableException 时找到一种方法来指定有效的响应媒体类型,以便 ResponseEntity 将其发送给客户端。由于无法确定请求的媒体类型,这可能只是我的服务的默认值(application/xml)

有什么想法吗?

最佳答案

我在开发中发现了同样的问题,要解决这个问题,您需要在 controllerAdvicer 的所有注释为 @ExceptionHandler 的方法中出现的错误消息的响应正文中指定> 内容类型:

例如:您的接收 header 接受:application/pdf,但您的应用程序生成application/json

GlobalExceptionHandler @ControllerAdvice注释来管理特定的主体响应:

    package com.obs.sfu.exception;

import javax.validation.ConstraintViolationException;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.ws.soap.client.SoapFaultClientException;

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

private static final String SIZE_MUST_BE_FROM_1_TO_15_CHARACTERS = "Size must be from 1 to 15 characters";
private static final int CODE_INTERNAL_SERVER_ERROR = 1;
private static final String MESSAGE_INTERNAL_SERVER_ERROR = "Internal error";
private static final String DESCRIPTION_INTERNAL_SERVER_ERROR = "Generic failure message";

private static final int CODE_SERVICE_UNAVAILABLE = 5;
private static final String MESSAGE_SERVICE_UNAVAILABLE = "The service is temporarily unavailable";
private static final String DESCRIPTION_SERVICE_UNAVAILABLE = "The service can not handle the call.";

private static final int CODE_UNSUPPORTED_MEDIA_TYPE = 68;
private static final String MESSAGE_UNSUPPORTED_MEDIA_TYPE = "Unsupported Media Type";
private static final String DESCRIPTION_UNSUPPORTED_MEDIA_TYPE = "The format of the posted body is not supported by the endpoint.";

private static final int CODE_NOT_FOUND = 60;
private static final String MESSAGE_NOT_FOUND = "Resource not found";
private static final String DESCRIPTION_NOT_FOUND = "The Requested URI or the requested resource does not exist.";

private static final int CODE_METHOD_NOT_ALLOWED = 61;
private static final String MESSAGE_METHOD_NOT_ALLOWED = "Method not allowed";
private static final String DESCRIPTION_METHOD_NOT_ALLOWED = "The URI does not support the requested method. The available methods should be set in the response header 'Allow'";

private static final int CODE_NOT_ACCEPTABLE = 62;
private static final String MESSAGE_NOT_ACCEPTABLE = "Not acceptable";
private static final String DESCRIPTION_NOT_ACCEPTABLE = "The Accept incoming header does not match any available content-type.";

private static final int CODE_CONSTRAINT_VIOLATION_FIELD = 20;
private static final String MESSAGE_INVALID_BODY_FIELD = "Invalid Via field";

private static final String HEADER_ALLOW = "Allow";
private static final String HEADER_ALLOW_VALUE = "GET, OPTIONS";

@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(request.getContextPath(), MESSAGE_NOT_FOUND, DESCRIPTION_NOT_FOUND,
CODE_NOT_FOUND);
return ResponseEntity.status(status).contentType(MediaType.APPLICATION_JSON).body(errorDetails);
}

@Override
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(request.getContextPath(), MESSAGE_METHOD_NOT_ALLOWED,
DESCRIPTION_METHOD_NOT_ALLOWED, CODE_METHOD_NOT_ALLOWED);
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set(HEADER_ALLOW, HEADER_ALLOW_VALUE);
return ResponseEntity.status(status).headers(responseHeaders).contentType(MediaType.APPLICATION_JSON)
.body(errorDetails);
}

@Override
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(request.getContextPath(), MESSAGE_UNSUPPORTED_MEDIA_TYPE,
DESCRIPTION_UNSUPPORTED_MEDIA_TYPE, CODE_UNSUPPORTED_MEDIA_TYPE);
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("Accept", MediaType.APPLICATION_JSON_VALUE);
return ResponseEntity.status(status).headers(responseHeaders).contentType(MediaType.APPLICATION_JSON)
.body(errorDetails);
}

@Override
protected ResponseEntity<Object> handleHttpMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(request.getContextPath(), MESSAGE_NOT_ACCEPTABLE,
DESCRIPTION_NOT_ACCEPTABLE, CODE_NOT_ACCEPTABLE);
return ResponseEntity.status(status).contentType(MediaType.APPLICATION_JSON).body(errorDetails);
}

@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(request.getContextPath(), MESSAGE_INVALID_BODY_FIELD,
SIZE_MUST_BE_FROM_1_TO_15_CHARACTERS, CODE_CONSTRAINT_VIOLATION_FIELD);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON).body(errorDetails);
}

@ExceptionHandler(SoapFaultClientException.class)
public ResponseEntity<Object> handleSoapFaultClient(Exception ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(request.getContextPath(), MESSAGE_SERVICE_UNAVAILABLE,
DESCRIPTION_SERVICE_UNAVAILABLE, CODE_SERVICE_UNAVAILABLE);
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).contentType(MediaType.APPLICATION_JSON)
.body(errorDetails);
}

@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleGlobalException(Exception ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(request.getContextPath(), MESSAGE_INTERNAL_SERVER_ERROR,
DESCRIPTION_INTERNAL_SERVER_ERROR, CODE_INTERNAL_SERVER_ERROR);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(MediaType.APPLICATION_JSON)
.body(errorDetails);
}
}

文件application.properties需要这些属性来管理NoHandlerFoundException(throwExceptionIfNoHandlerFound):

spring:
mvc:
throw-exception-if-no-handler-found: true
static-path-pattern: /swagger* # to available swagger-ui.html

关于java - Spring MVC - 处理 HttpMediaTypeNotAcceptableException 时如何设置返回媒体类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14762447/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com