首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >REST-API不同内容-错误响应类型

REST-API不同内容-错误响应类型
EN

Stack Overflow用户
提问于 2015-06-17 11:14:10
回答 2查看 12.5K关注 0票数 11

从几周以来,我一直在使用spring编写rest。REST工作正常,当涉及到对特定错误对象的错误处理时,我几乎完成了最后一个问题。

REST-API使用JSON作为格式来序列化Java对象。当服务执行过程中发生错误时,将创建特定的错误对象并将其发送回客户端。

当我的rest服务标记为"produces=application/json“时,一切正常。但是也有一些服务只需要使用“produces= text /平原”返回简单文本。当这些服务中出现错误时,Spring将抛出一个HttpMediaTypeNotAcceptableException。这似乎是正确的,因为客户端要求内容类型为“text/平原”,而服务器响应则使用"application/json“。

你能告诉我这个问题的正确解决办法吗?

  1. 只有使用JSON作为响应内容类型和包装简单的文本总是在一个特殊的类对象。在我看来,=>并不是真正的REST,因为REST应该支持多种内容类型。
  2. 服务"text“的每个服务都将标记为”produces=application/json;text/平原“,客户端也需要在"accept-header”中同时发送这两个服务。=>这样做时,API似乎支持同一资源的两种内容类型。但这不对。只有在出现错误时,API才会返回JSON,否则它将始终是"text“。

听起来像是一个很特别的休息问题,也找不到关于这个话题的相关问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-17 11:22:22

用户应该始终指定它期望使用Accept头的内容。您的任务是以Accept标头中指定的格式返回服务器端抛出/捕获的错误。在春天,据我所知,它可以用一个特殊的地图。下面可以找到用groovy编写的这样一个映射器来处理text/html

代码语言:javascript
运行
复制
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类:

代码语言:javascript
运行
复制
class ExceptionResponse {
  String error
  String exception
  String message
  String path
  Integer status
  Long timestamp
}
票数 4
EN

Stack Overflow用户

发布于 2019-03-25 17:44:40

我面临着同样的问题,对于其他的最佳实践,我也有同样的问题。

我所读到的关于处理API响应中的错误的所有文章都使用JSON。例如这里

我不认为所有这些API总是用JSON包装数据。有时你只需要提供文件,短信或非json之类的东西.此外,我偶然发现了RFC7807,它提出了用JSON格式公开错误/问题的标准方法,甚至使用它自己的内容类型的应用程序/问题+json。因此,我们可以安全地假设,对于HTTP 200使用不同的内容类型而不是对HTTP错误代码使用不同的内容类型是一个很好的实践。

关于如何使用Spring框架实现它,它实际上非常简单。一旦您理解了"produces ={}“基本上是一种声明式的方式来表示您的响应将是某种类型,您就可以想象,也可以通过编程方式设置要返回的类型。

下面是一个API示例,它应该返回应用程序/八位流(一个二进制文件)。

代码语言:javascript
运行
复制
@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))));
}

当它工作时,它将返回一个具有正确内容类型的文件。现在,如果您想处理错误案例(在本例中是一个错误的字符集参数),您可以创建一个异常处理程序:

代码语言:javascript
运行
复制
@ExceptionHandler(UnsupportedCharsetException.class)
public ResponseEntity<?> handleCharsetException(UnsupportedCharsetException e) {
    return ResponseEntity.badRequest().contentType(MediaType.APPLICATION_JSON_UTF8).body(new ErrorResponse("1", "Wrong charset"));
}

现在,错误案例也如预期的那样工作:

代码语言:javascript
运行
复制
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"
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30889928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档