我在jersey servlet中有一个方法,它使用MULTIPART_FORM_DATA和application / x-www-form-urlencoded媒体类型,在我的请求中,我发送了一些参数以及文件输入流中的文件。
这是我的方法
@POST
@Path("/upload")
@Consumes({MediaType.MULTIPART_FORM_DATA,MediaType.APPLICATION_FORM_URLENCODED})
@Produces(MediaType.TEXT_PLAIN)
public String uploadFile(MultivaluedMap<String,String> requestParamsPost,@FormDataParam("file") InputStream fis,
@FormDataParam("file") FormDataContentDisposition fdcd){
//some code goes here
}
但我的问题是当我在web.xml中进行servlet映射后启动服务器时,我遇到了一些严重的异常
SEVERE: Missing dependency for method public javax.ws.rs.core.Response com.package.ImportService.uploadFile(java.lang.String,java.lang.String,java.lang.String) at parameter at index 0
SEVERE: Missing dependency for method public javax.ws.rs.core.Response com.package.ImportService.uploadFile(java.lang.String,java.lang.String,java.lang.String) at parameter at index 1
SEVERE: Missing dependency for method public javax.ws.rs.core.Response com.package.ImportService.uploadFile(java.lang.String,java.lang.String,java.lang.String) at parameter at index 2
在单个端点上以一种方法使用两种媒体类型是否可行? 发送文件每个请求都需要参数吗?
答案 0 :(得分:0)
错误的原因是MultivaluedMap
参数。泽西岛不知道该怎么做。每个方法只能有一个实体类型。在您的方法中,您尝试在请求中接受两种不同的体型。你不能这样做。我甚至不知道你打算如何从客户那里发送它。
application/x-www-form-urlencoded
数据需要成为多部分正文的一部分。所以你可以做到
@Consumes({MediaType.MULTIPART_FORM_DATA})
public String uploadFile(@FormDataMultiPart("form-data") MultivaluedMap<String,String> form,
@FormDataParam("file") InputStream fis,
@FormDataParam("file") FormDataContentDisposition fdcd){
那会有用。唯一的问题是,您需要确保客户端设置Content-Type
部分的form-data
。如果他们不这样做,那么默认的Content-Type for that part will be
text / plain and Jersey will not be able to parse it to a
MultivaluedMap`。
您可以做的只是使用FormDataBodyPart
作为方法参数,然后显式设置媒体类型。然后,您可以将其提取到MultivaluedMap
。这样,客户端不需要为该部分设置Content-Type
。有些客户甚至不允许设置单独的零件类型。
import java.util.logging.Logger;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.filter.LoggingFilter;
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.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
public class MultipartTest extends JerseyTest {
@Path("test")
public static class MultiPartResource {
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response post(@FormDataParam("form-data") FormDataBodyPart bodyPart,
@FormDataParam("data") String data) {
bodyPart.setMediaType(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
MultivaluedMap<String, String> formData = bodyPart.getEntityAs(MultivaluedMap.class);
StringBuilder sb = new StringBuilder();
sb.append(data).append(";").append(formData.getFirst("key"));
return Response.ok(sb.toString()).build();
}
}
@Override
public ResourceConfig configure() {
return new ResourceConfig(MultiPartResource.class)
.register(MultiPartFeature.class)
.register(new LoggingFilter(Logger.getAnonymousLogger(), true));
}
@Override
public void configureClient(ClientConfig config) {
config.register(MultiPartFeature.class);
}
@Test
public void doit() {
FormDataMultiPart multiPart = new FormDataMultiPart();
multiPart.field("data", "hello");
multiPart.field("form-data", "key=world");
final Response response = target("test")
.request().post(Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA));
assertEquals("hello;world", response.readEntity(String.class));
}
}
如果查看日志记录,您会看到请求为
--Boundary_1_323823279_1458137333706
Content-Type: text/plain
Content-Disposition: form-data; name="data"
hello
--Boundary_1_323823279_1458137333706
Content-Type: text/plain
Content-Disposition: form-data; name="form-data"
key=world
--Boundary_1_323823279_1458137333706--
您可以看到Content-Type
正文部分form-data
为text/plain
,这是默认设置,但在服务器端,我们在Jersey解析它之前明确设置它
public Response post(@FormDataParam("form-data") FormDataBodyPart bodyPart,
@FormDataParam("data") String data) {
bodyPart.setMediaType(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
MultivaluedMap<String, String> formData = bodyPart.getEntityAs(MultivaluedMap.class);