你不能有两个Content-Type
(技术上这是我们下面做的,但它们与多部分的每个部分分开,但主要类型是多部分)。这基本上是你用你的方法期待的。您正在期待将mutlipart 和 json作为主要媒体类型。 Employee
数据需要成为multipart的一部分。因此,您可以为Employee
添加@FormDataParam("emp")
。
@FormDataParam("emp") Employee emp) { ...
这是我用来测试
@Path("/multipart")
public class MultipartResource {
@POST
@Path("/upload2")
@Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadFileWithData(
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition cdh,
@FormDataParam("emp") Employee emp) throws Exception{
Image img = ImageIO.read(fileInputStream);
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(img)));
System.out.println(cdh.getName());
System.out.println(emp);
return Response.ok("Cool Tools!").build();
}
}
首先,我只是用客户端API测试,以确保它工作
@Test
public void testGetIt() throws Exception {
final Client client = ClientBuilder.newBuilder()
.register(MultiPartFeature.class)
.build();
WebTarget t = client.target(Main.BASE_URI).path("multipart").path("upload2");
FileDataBodyPart filePart = new FileDataBodyPart("file",
new File("stackoverflow.png"));
// UPDATE: just tested again, and the below code is not needed.
// It's redundant. Using the FileDataBodyPart already sets the
// Content-Disposition information
filePart.setContentDisposition(
FormDataContentDisposition.name("file")
.fileName("stackoverflow.png").build());
String empPartJson
= "{\n"
+ " \"id\": 1234,\n"
+ " \"name\": \"Peeskillet\"\n"
+ "}\n"
+ "";
MultiPart multipartEntity = new FormDataMultiPart()
.field("emp", empPartJson, MediaType.APPLICATION_JSON_TYPE)
.bodyPart(filePart);
Response response = t.request().post(
Entity.entity(multipartEntity, multipartEntity.getMediaType()));
System.out.println(response.getStatus());
System.out.println(response.readEntity(String.class));
response.close();
}
我刚刚创建了一个简单Employee
类与类id
和name
字段进行测试。这工作非常好。它显示图像,打印内容配置,并打印Employee
对象。
我不是太熟悉的邮差,所以我保存的测试去年:-)
这似乎做工精细而且,正如你所看到的响应"Cool Tools"
。但是,如果我们查看打印的Employee
数据,我们会看到它是空的。这很奇怪,因为客户端API工作正常。
如果我们在预览窗口中,我们将看到的问题
有没有Content-Type
标题为emp
身体部位。您可以将客户端API中看到我明确设置
MultiPart multipartEntity = new FormDataMultiPart()
.field("emp", empPartJson, MediaType.APPLICATION_JSON_TYPE)
.bodyPart(filePart);
所以我想这是真的只有一个完整的答案的一部分。就像我说的,我对邮差不熟悉所以我不知道如何为个人身体部位设置Content-Type
。该图像的image/png
是我为图像部分明确设置的。如果你能弄清楚这个问题,那么问题应该解决。请,如果你发现如何做到这一点,请将其作为答案。
而只是为了完整性......
基本配置:
相关性:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.14</version>
</dependency>
客户端配置:
final Client client = ClientBuilder.newBuilder()
.register(MultiPartFeature.class)
.build();
服务器配置:
// Create JAX-RS application.
final Application application = new ResourceConfig()
.packages("org.glassfish.jersey.examples.multipart")
.register(MultiPartFeature.class);
UPDATE
所以你可以从邮差客户端看到,某些客户端将无法设置单个零件的内容类型,这包括浏览器,在关于它使用时的默认功能FormData
(JS)。
我们不能指望客户找到这个东西,所以我们可以做的是在接收数据时,在反序列化之前明确设置Content-Type。例如
@POST
@Path("upload2")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFileAndJSON(@FormDataParam("emp") FormDataBodyPart jsonPart,
@FormDataParam("file") FormDataBodyPart bodyPart) {
jsonPart.setMediaType(MediaType.APPLICATION_JSON_TYPE);
Employee emp = jsonPart.getValueAs(Employee.class);
}
这是一些额外的工作来获得POJO,但它比强制客户端,试图找到它自己的解决方案更好的解决方案。
嗨,我可以请你麻烦你(或任何其他善良的灵魂谁读这个,知道)更新客户端API中的代码。例如,第一行有“c.target”,但这里的c是什么? – AbuMariam
@ user3223841请参阅最底部的“客户端配置”。 'c == client'。我更新了代码。谢谢。 –
你在大文件上测试过你的代码吗?我在表单提交时得到[相同](http://stackoverflow.com/q/10326460/660408)错误 – gkiko