我是java rest应用程序的新手。 我试图运行一个应用程序,但我有这个例外
message com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type, class java.util.ArrayList, and MIME media type, multipart/form-data, was not found
exception
com.sun.jersey.api.client.ClientHandlerException: com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type, class java.util.ArrayList, and MIME media type, multipart/form-data, was not found
com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:155)
com.sun.jersey.api.client.Client.handle(Client.java:652)
com.sun.jersey.api.client.WebResource.handle(WebResource.java:682)
com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570)
org.eu.paas.client.APIClient.doPost(APIClient.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
在APIClient.java:265
我有一些事情:
cr = service.path(path)
.type(MediaType.MULTIPART_FORM_DATA)
.post(ClientResponse.class, listForm);
listForm
是ArrayList<InputStream>
在其他申请中我有:
@POST
@Path("{appId-appId}/action/Multideploy/env/{envId-envId}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_XML)
Response MultideployApplication(
@PathParam("appId-appId") String appid, @PathParam("envId-envId") String envid,
@FormDataParam("file") List<InputStream> uploadedInputStream);
同样在我的pom.xml中,我有这些依赖项:
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.18</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
答案 0 :(得分:5)
Jersey使用MessageBodyWriter
来处理请求流(或服务器端的响应流,以及MessageBodyReader
)的Java对象序列化以处理 de - 序列化响应流(或服务器端的请求流)到Java对象。您可以在JAX-RS Entity Providers了解更多信息。
话虽这么说,每当你看到像&#34;没有找到类型的MessageBodyReader(Writer)这样的错误以及java类型某某&#34; 时,它意味着有没有序列化程序来处理转换。在您的特定情况下,它表示没有编写者可以处理ArrayList
到multipart / form-data的转换。这是有道理的,因为作者将如何知道如何进行这种转换。
对于multipart,您需要在客户端客户端实际使用多部分API。作者知道如何将这些API对象转换为所需的多部分。有关API的完整列表,您可以查看包com.sun.jersey.multipart
。
以下是发送文件的示例
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
public String getTest(@FormDataParam("file") InputStream in,
@FormDataParam("file") FormDataContentDisposition fdc) {
try (FileOutputStream out = new FileOutputStream(fdc.getFileName())) {
ReaderWriter.writeTo(in, out);
} catch (IOException ex) {
ex.printStackTrace(System.out);
return "Bad $#!t happended";
}
return "Upload OK";
}
@Test
public void doit() {
File file = new File("...");
FileDataBodyPart filePart = new FileDataBodyPart("file", file);
MultiPart entity = new FormDataMultiPart()
.bodyPart(filePart);
Client client = Client.create();
WebResource resource = client.resource("http://localhost:9998/service");
ClientResponse response = resource
.type(MediaType.MULTIPART_FORM_DATA_TYPE)
.post(ClientResponse.class, entity);
assertEquals(200, response.getStatus());
assertEquals("Upload OK", response.getEntity(String.class));
response.close();
}
对于Jersey multipart的1.x支持,实际上没有任何文档。但很多时候,测试中都会看到最好的文档。因此,如果您想要更多示例,请look at the tests for jersey-multipart。
这是使用Jersey Test Framework的完整测试。像任何其他JUnit测试一样运行它。将常量FILE_ONE
和FILE_TWO
替换为系统上某些任意文件的位置。您应该看到保存到当前工作目录的文件(很可能是项目根目录)
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.core.DefaultResourceConfig;
import com.sun.jersey.core.header.ContentDisposition;
import com.sun.jersey.core.util.ReaderWriter;
import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataMultiPart;
import com.sun.jersey.multipart.FormDataParam;
import com.sun.jersey.multipart.MultiPart;
import com.sun.jersey.multipart.file.FileDataBodyPart;
import com.sun.jersey.spi.container.servlet.WebComponent;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.WebAppDescriptor;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* Run this like any other JUnit test. Dependencies for test are as follows.
*
* <jersey.version>1.19</jersey.version>
*
* <dependency>
* <groupId>com.sun.jersey</groupId>
* <artifactId>jersey-servlet</artifactId>
* <version>${jersey.version}</version>
* </dependency>
* <dependency>
* <groupId>com.sun.jersey</groupId>
* <artifactId>jersey-servlet</artifactId>
* <version>${jersey.version}</version>
* </dependency>
* <dependency>
* <groupId>com.sun.jersey.jersey-test-framework</groupId>
* <artifactId>jersey-test-framework-grizzly2</artifactId>
* <version>1.19</version>
* <scope>test</scope>
* </dependency>
* <dependency>
* <groupId>com.sun.jersey.contribs</groupId>
* <artifactId>jersey-multipart</artifactId>
* <version>${jersey.version}</version>
* </dependency>
*
*/
public class MultipartTest extends JerseyTest {
@Path("service")
public static class Service {
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
public String getTest(@FormDataParam("file") List<FormDataBodyPart> files) {
for (FormDataBodyPart filePart: files) {
ContentDisposition cd = filePart.getContentDisposition();
try (FileOutputStream out = new FileOutputStream(cd.getFileName())) {
ReaderWriter.writeTo(filePart.getEntityAs(InputStream.class), out);
} catch (IOException ex) {
ex.printStackTrace(System.out);
return "Oops";
}
}
return "Upload OK";
}
}
public static class AppConfig extends DefaultResourceConfig {
public AppConfig() {
super(Service.class);
}
}
@Override
public WebAppDescriptor configure() {
return new WebAppDescriptor.Builder()
.initParam(WebComponent.RESOURCE_CONFIG_CLASS,
AppConfig.class.getName())
.build();
}
private static final String FILE_ONE = "<enter-a-file-path>";
private static final String FILE_TWO = "<enter-a-file-path>";
@Test
public void doit() {
File file1 = new File(FILE_ONE);
File file2 = new File(FILE_TWO);
MultiPart entity = new FormDataMultiPart();
FileDataBodyPart filePart = new FileDataBodyPart("file", file1);
entity.bodyPart(filePart);
filePart = new FileDataBodyPart("file", file2);
entity.bodyPart(filePart);
ClientResponse response = resource().path("service")
.type(MediaType.MULTIPART_FORM_DATA_TYPE)
.post(ClientResponse.class, entity);
assertEquals(200, response.getStatus());
assertEquals("Upload OK", response.getEntity(String.class));
response.close();
}
}
以下是与Jersey 2.x相同的测试。只需将常量FILE_ONE
和FILE_TWO
替换为系统上的某些文件位置,然后运行测试。这些文件应保存到您当前的工作目录中。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.media.multipart.ContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
import org.glassfish.jersey.message.internal.ReaderWriter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
/**
* Run it like any other JUnit test. Required dependencies are as follows:
*
* <dependency>
* <groupId>org.glassfish.jersey.test-framework.providers</groupId>
* <version>2.22.1</version>
* <scope>test</scope>
* </dependency>
* <dependency>
* <groupId>org.glassfish.jersey.media</groupId>
* <artifactId>jersey-media-multipart</artifactId>
* <version>2.22.1</version>
* <scope>test</scope>
* </dependency>
*
*/
public class Jersey2MultipartTest extends JerseyTest {
@Path("service")
public static class Service {
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
public String getTest(@FormDataParam("file") List<FormDataBodyPart> files) {
for (FormDataBodyPart filePart: files) {
ContentDisposition cd = filePart.getContentDisposition();
try (FileOutputStream out = new FileOutputStream(cd.getFileName())) {
ReaderWriter.writeTo(filePart.getEntityAs(InputStream.class), out);
} catch (IOException ex) {
ex.printStackTrace(System.out);
return "Oops";
}
}
return "Upload OK";
}
}
@Override
public ResourceConfig configure() {
return new ResourceConfig(Service.class)
.register(MultiPartFeature.class);
}
@Override
public void configureClient(ClientConfig config) {
config.register(MultiPartFeature.class);
}
private static final String FILE_ONE = "<enter-file-location>";
private static final String FILE_TWO = "<enter-file-location>";
@Test
public void doit() {
MultiPart entity = new FormDataMultiPart();
addFiles(entity, FILE_ONE, FILE_TWO);
Response response = target("service").request()
.post(Entity.entity(entity, MediaType.MULTIPART_FORM_DATA));
assertEquals(200, response.getStatus());
assertEquals("Upload OK", response.readEntity(String.class));
response.close();
}
private void addFiles(MultiPart entity, String... files) {
for (String file: files) {
FileDataBodyPart filePart = new FileDataBodyPart("file", new File(file));
entity.bodyPart(filePart);
}
}
}