从几周以来,我一直在使用spring编写rest。REST工作正常,当涉及到对特定错误对象的错误处理时,我几乎完成了最后一个问题。
REST-API使用JSON作为格式来序列化Java对象。当服务执行过程中发生错误时,将创建特定的错误对象并将其发送回客户端。
当我的rest服务标记为"produces=application/json“时,一切正常。但是也有一些服务只需要使用“produces= text /平原”返回简单文本。当这些服务中出现错误时,Spring将抛出一个HttpMediaTypeNotAcceptableException。这似乎是正确的,因为客户端要求内容类型为“text/平原”,而服务器响应则使用"application/json“。
你能告诉我这个问题的正确解决办法吗?
听起来像是一个很特别的休息问题,也找不到关于这个话题的相关问题。
发布于 2015-06-17 11:22:22
用户应该始终指定它期望使用Accept
头的内容。您的任务是以Accept
标头中指定的格式返回服务器端抛出/捕获的错误。在春天,据我所知,它可以用一个特殊的地图。下面可以找到用groovy编写的这样一个映射器来处理text/html
。
import groovy.xml.MarkupBuilder
import org.springframework.http.HttpInputMessage
import org.springframework.http.HttpOutputMessage
import org.springframework.http.converter.AbstractHttpMessageConverter
import static org.springframework.http.MediaType.TEXT_HTML
class ExceptionResponseHTMLConverter extends AbstractHttpMessageConverter<ExceptionResponse> {
ExceptionResponseHTMLConverter() {
super(TEXT_HTML)
}
@Override
boolean supports(Class clazz) {
clazz.equals(ExceptionResponse)
}
@Override
ExceptionResponse readInternal(Class clazz, HttpInputMessage msg) {
throw new UnsupportedOperationException()
}
@Override
void writeInternal(ExceptionResponse e, HttpOutputMessage msg) {
def sw = new StringWriter()
new MarkupBuilder(sw).error {
error(e.error)
exception(e.exception)
message(e.message)
path(e.path)
status(e.status)
timestamp(e.timestamp)
}
msg.body << sw.toString().bytes
}
}
和ExceptionResponse
类:
class ExceptionResponse {
String error
String exception
String message
String path
Integer status
Long timestamp
}
发布于 2019-03-25 17:44:40
我面临着同样的问题,对于其他的最佳实践,我也有同样的问题。
我所读到的关于处理API响应中的错误的所有文章都使用JSON。例如这里。
我不认为所有这些API总是用JSON包装数据。有时你只需要提供文件,短信或非json之类的东西.此外,我偶然发现了RFC7807,它提出了用JSON格式公开错误/问题的标准方法,甚至使用它自己的内容类型的应用程序/问题+json。因此,我们可以安全地假设,对于HTTP 200使用不同的内容类型而不是对HTTP错误代码使用不同的内容类型是一个很好的实践。
关于如何使用Spring框架实现它,它实际上非常简单。一旦您理解了"produces ={}“基本上是一种声明式的方式来表示您的响应将是某种类型,您就可以想象,也可以通过编程方式设置要返回的类型。
下面是一个API示例,它应该返回应用程序/八位流(一个二进制文件)。
@GetMapping(path = "/1/resources/hello", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
public ResponseEntity<StreamingResponseBody> getFile(@RequestParam(value = "charset", required = false, defaultValue = "UTF-8") String charset) {
return ResponseEntity.ok().body(outputStream -> outputStream.write("Hello there".getBytes(Charset.forName(charset))));
}
当它工作时,它将返回一个具有正确内容类型的文件。现在,如果您想处理错误案例(在本例中是一个错误的字符集参数),您可以创建一个异常处理程序:
@ExceptionHandler(UnsupportedCharsetException.class)
public ResponseEntity<?> handleCharsetException(UnsupportedCharsetException e) {
return ResponseEntity.badRequest().contentType(MediaType.APPLICATION_JSON_UTF8).body(new ErrorResponse("1", "Wrong charset"));
}
现在,错误案例也如预期的那样工作:
GET http://localhost/1/resources/hello?charset=CRAP
HTTP/1.1 400 Bad Request
Connection: keep-alive
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8
Date: Mon, 25 Mar 2019 17:37:39 GMT
{
"code": "1",
"message": "Wrong charset"
}
https://stackoverflow.com/questions/30889928
复制相似问题