5

我正在使用带有杰克逊的 Restlet 2.1 来构建一个 json REST api。

当我使用预期的内容类型但正文格式错误的请求时,我会返回 415“不支持的媒体类型”状态代码。我认为正确的错误代码应该是 400 "Bad Request"。

显然,当杰克逊尝试解码垃圾但未能解码时,就会发生混淆。

我将尝试使用一些代码使案例更清楚:

// java method mapping
@Post("json")
public Project create(Project project) {

使用 curl 调用服务

$ curl -i -XPOST -H 'content-type: application/json' -d '{xgarbage}' http://localhost:8080/projects HTTP/1.1 415 Unsupported Media Type

以及日志中记录的堆栈跟踪操作系统片段:

Nov 29, 2010 9:51:56 PM org.restlet.ext.jackson.JacksonRepresentation getObject
WARNING: Unable to parse the object with Jackson.
org.codehaus.jackson.JsonParseException: Unexpected character ('x' (code 120)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
 at [Source: java.io.ByteArrayInputStream@693e4a5a; line: 1, column: 2]
at org.codehaus.jackson.JsonParser._constructError(JsonParser.java:929)

服务的实际实现永远不会受到影响,因此在某个地方做出了将乱码内容映射到 415 的决定。

现在,我的问题是:这是正确的吗?如果我正确阅读“RESTful Web Services”一书中的以下引语,那不是,但我愿意更正。

[400 Bad Request] 通常在客户端提交表示连同 PUT 或 POST 请求时使用,并且表示格式正确,但没有任何意义。

.

[415 Unsupported Media Type] 如果客户端发送的文档具有正确的媒体类型但格式错误(例如使用错误词汇表编写的 XML 文档),则更好的响应是更通用的 400(“错误请求”)

对或错,我宁愿退回400。

有没有办法在不放弃杰克逊提供的自动魔法序列化的情况下改变行为?

非常感谢任何帮助,谢谢!

4

1 回答 1

3

415 是正确的,因为如果请求无论如何都已损坏,则该请求的格式不正确。例如不可解析的 JSON 或 XML。畸形的 JSON 或XML 根据定义不是JSON 或 XML,因此是不受支持的媒体类型,Jackson 无法知道它应该是 JSON,它只知道它可以解析的不是 JSON。

官方文档对此非常清楚。

10.4.16 415 不支持的媒体类型

服务器拒绝为请求提供服务,因为请求的实体采用所请求方法的请求资源不支持的格式。

你说,嘿,这是 JSON,但服务器不是这样说的,嘿,我得到的不是 JSON,并且不受此资源的支持。

于 2010-11-30T00:04:07.967 回答