当前位置: 首页 > 知识库问答 >
问题:

在Jersey restful web服务中与其他对象一起上载文件

徐承载
2023-03-14

我想通过上载一个图像和员工数据在系统中创建一个员工信息。我可以使用Jersey使用不同的rest调用。但我想在一次rest调用中实现。我提供了下面的结构。请帮我在这方面怎么做。

@POST
@Path("/upload2")
@Consumes({MediaType.MULTIPART_FORM_DATA,MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response uploadFileWithData(
        @FormDataParam("file") InputStream fileInputStream,
        @FormDataParam("file") FormDataContentDisposition contentDispositionHeader,
        Employee emp) {

//..... business login

}

每当我试图做,我得到错误在Chrome邮差。下面给出了我的Employee json的简单结构。

{
    "Name": "John",
    "Age": 23,
    "Email": "john@gmail.com",
    "Adrs": {
        "DoorNo": "12-A",
        "Street": "Street-11",
        "City": "Bangalore",
        "Country": "Karnataka"
    }
}

共有1个答案

景英杰
2023-03-14

不能有两个content-type(从技术上讲,这就是我们下面要做的,但它们与multipart的每个部分分开,但主要类型是multipart)。这基本上是您的方法所期望的。您希望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
            = "{"
            + "  \"id\": 1234,"
            + "  \"name\": \"Peeskillet\""
            + "}";

    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();
}

emp正文部分没有content-type头。您可以在我显式设置的客户端API中看到

MultiPart multipartEntity = new FormDataMultiPart()
        .field("emp", empPartJson, MediaType.APPLICATION_JSON_TYPE)
        .bodyPart(filePart);

所以我想这只是一个完整答案的一部分。就像我说的,我不熟悉Postman,所以我不知道如何为单个身体部分设置content-types。图像的image/png是自动为我为图像部分设置的(我猜这只是由文件扩展名决定的)。如果你能弄清楚这一点,那么问题应该就解决了。拜托,如果你找到了如何做到这一点,贴出来作为一个答案。

有关解决方案,请参阅下面的更新

    null
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>${jersey2.version}</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);

如果您在服务器配置方面遇到问题,下面的文章可能会有所帮助

  • Jersey 2中的ResourceConfig类到底是什么?
  • 152 multipart_form_data:未找到public javax.ws.rs.core.response类型参数的注入源
@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);
}
  • 如果您使用的连接器不同于默认的HTTPURLConnection,则这些注释中有一个对话可能会引起您的兴趣。
 类似资料:
  • 我有一个html。我需要上传图像和angularjs和spring rest服务中的其他表单字段。下面是html。 以下是Spring控制器方法。 在上面的代码中,我想上传文件以及数据字段。我使用的是角js和Spring rest服务。如何在js中发送文件以及数据,以及如何在Spring控制器中获取值。我的意思是我应该在上传图像()方法中使用哪些参数来获取控制器中的表单数据字段和文件。 添加控制器

  • 问题内容: 我想通过上传图像和员工数据来在系统中创建员工信息。我可以使用球衣使用其他休息电话来做到这一点。但我想在一个电话会议中实现。我在下面提供结构。请帮我在这方面怎么做。 每当我尝试执行此操作时,Chrome邮递员都会出现错误。我的Employee json的简单结构如下。 但是,我可以通过拨打两个不同的电话来做到这一点,但我想在一个休息电话中实现,这样我就可以接收文件以及员工的实际数据。 请

  • 问题内容: 我正在使用jQuery将文件上传到服务器: 我想将其他参数与文件一起发送。可能吗?如果是,怎么办? 谢谢! 问题答案: 要发送其他参数,您可以将其附加到如下所示:

  • Navicat 还能让你管理其他 SQLite 对象:索引和触发器。在主窗口的主工具栏点击相应的按钮来打开对象列表。

  • Navicat 还能让你管理其他 SQL Server 对象:索引、同义词、触发器、备份设备、链接服务器、服务器触发器、程序集、数据库触发器、分区函数和分区方案。在主窗口中,点击 “其他”,然后选择一个对象来打开对象列表。

  • Navicat 还能让你管理其他 PostgreSQL 对象:聚合、转换、域、索引、运算符、运算符类别、序列、触发器、表空间、编制和语言。在主窗口中,点击 “其他”,然后选择一个对象来打开对象列表。