同时支持 APPLICATION_JSON 和 MULTIPART_FORM_DATA 的 Jersey2 无法接受 JSON 输入
Jersey2 supporting both APPLICATION_JSON and MULTIPART_FORM_DATA fails to accept JSON input
我是 Jersey 的新手,正在尝试实现一个 POST 端点,它可以分别接受 application/json 和 multipart/form-data 内容类型。
@POST
@Path("/upload")
@Consumes({MediaType.APPLICATION_JSON, MediaType.MULTIPART_FORM_DATA})
@Produces({MediaType.APPLICATION_JSON, MediaType.MULTIPART_FORM_DATA})
public void upload(@FormDataParam("jsonInput") MyPojo req,
@FormDataParam("file") FormDataBodyPart file)
{
//...
}
以下是 Spring 引导依赖项:
dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
我通过扩展 ResourceConfig 和注册我的 REST 配置了必要的资源 API 类 还包括一些如下所示的标准资源:
register(MyRestImpl.class);
register(JacksonFeature.class);
register(MultiPartFeature.class);
“jersey-media-json-jackson”已经添加到 Maven 依赖项中,它应该处理 serialize/deserialize POJO。
现在,我看到发送 JSON 输入作为多部分请求的一部分,工作正常。
然而,发送与 Content-Type: application/json 相同的 JSON 输入甚至无法访问服务,Postman 报告以下反序列化错误:
Cannot find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]]
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]
为什么以 application/json Content-Type 发送 JSON 数据不起作用,而以 multipart/form-data Content-Type 发送相同的 JSON 数据有效?
我不认为,我们需要为此注释任何特别的东西,对吗?
在同一方法中同时接受 multipart 和 JSON 是行不通的。原因是它们不能正确反序列化为相同的对象和不同数量的参数和注释,以支持多部分。不过,您可以做的是 两个 方法(针对相同的 URL),每个方法具有不同的媒体类型。
@POST
@Path("/upload")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public void json(JsonPojo pojo) { }
@POST
@Path("/upload")
@Consumes({MediaType.MULTIPART_FORM_DATA})
@Produces({MediaType.APPLICATION_JSON})
public void upload(@FormDataParam("jsonInput") MyPojo req,
@FormDataParam("file") FormDataBodyPart file) { }
我是 Jersey 的新手,正在尝试实现一个 POST 端点,它可以分别接受 application/json 和 multipart/form-data 内容类型。
@POST
@Path("/upload")
@Consumes({MediaType.APPLICATION_JSON, MediaType.MULTIPART_FORM_DATA})
@Produces({MediaType.APPLICATION_JSON, MediaType.MULTIPART_FORM_DATA})
public void upload(@FormDataParam("jsonInput") MyPojo req,
@FormDataParam("file") FormDataBodyPart file)
{
//...
}
以下是 Spring 引导依赖项:
dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
我通过扩展 ResourceConfig 和注册我的 REST 配置了必要的资源 API 类 还包括一些如下所示的标准资源:
register(MyRestImpl.class);
register(JacksonFeature.class);
register(MultiPartFeature.class);
“jersey-media-json-jackson”已经添加到 Maven 依赖项中,它应该处理 serialize/deserialize POJO。
现在,我看到发送 JSON 输入作为多部分请求的一部分,工作正常。 然而,发送与 Content-Type: application/json 相同的 JSON 输入甚至无法访问服务,Postman 报告以下反序列化错误:
Cannot find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]]
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]
为什么以 application/json Content-Type 发送 JSON 数据不起作用,而以 multipart/form-data Content-Type 发送相同的 JSON 数据有效? 我不认为,我们需要为此注释任何特别的东西,对吗?
在同一方法中同时接受 multipart 和 JSON 是行不通的。原因是它们不能正确反序列化为相同的对象和不同数量的参数和注释,以支持多部分。不过,您可以做的是 两个 方法(针对相同的 URL),每个方法具有不同的媒体类型。
@POST
@Path("/upload")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public void json(JsonPojo pojo) { }
@POST
@Path("/upload")
@Consumes({MediaType.MULTIPART_FORM_DATA})
@Produces({MediaType.APPLICATION_JSON})
public void upload(@FormDataParam("jsonInput") MyPojo req,
@FormDataParam("file") FormDataBodyPart file) { }