Исключение клиента на Джерси: не найден автор тела сообщения
Я использую клиент Джерси, чтобы запустить веб-сервис PHP для функции загрузки изображений. Я получаю следующее исключение:
Caused by: com.sun.jersey.api.client.ClientHandlerException:
A message body writer for Java type, class
com.sun.jersey.multipart.FormDataMultiPart, and MIME media type,
multipart/form-data, was not found
at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:288)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:204)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:147)
... 63 more
Это код, который я использую:
WebResource webResource = Client.create().resource(HTTP_REST_URI);
JSONObject jSONObj = webResource.queryParams(queryParams)
.type(MediaType.MULTIPART_FORM_DATA)
.post(JSONObject.class, formDataMultiPart);
Как можно разрешить это исключение?
6 ответов
Зарегистрировать MultiPartWriter
поставщик при создании Client
:
ClientConfig cc = new DefaultClientConfig();
Client client;
cc.getClasses().add(MultiPartWriter.class);
client = Client.create(cc);
Если вы используете Maven, это зависимости, которые вам нужны в вашем pom.xml
:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.17.1</version>
</dependency>
На Джерси (сервер или клиент) есть провайдеры, которые поддерживают преобразование типа Java в поток и наоборот. Ваш код возвращает (или получает) объект Java, и в зависимости от типа объекта и типа контента, который вы используете, Джерси ищет подходящего поставщика для выполнения маршалинга (или демаршаллинга).
Поставщики реализуют интерфейсы MessageBodyReader или MessageBodyWriter, и для каждой комбинации типов Java и типов контента, используемой вашим приложением, у вас должен быть поставщик, который знает, как обрабатывать эту комбинацию.
Сообщения, которые вы получаете, говорят о том, что Джерси не может найти поставщика, который знает, как организовать FormDataMultiPart
объект с multipart/form-data
тип пантомимы. Вы должны предоставить один, и если я не ошибаюсь, реализация по умолчанию находится в jersey-multipart.jar
а также mimepull.jar
файлы
Я столкнулся с той же проблемой. Это было решено путем изменения зависимости maven для jarsey-multipart jar с версии 1.0.2 до версии 1.8 (использовалась та же зависимость на стороне клиента, а также на стороне поставщика).
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.8</version>
</dependency>
Вот полный кусок кода, который я использую
File file = new File("E:/Goodies/tmp/sparrow.jpg");
byte[] logo = FileUtils.readFileToByteArray(file);
MultiPart multiPart = new MultiPart().bodyPart(new BodyPart(logo, MediaType.APPLICATION_OCTET_STREAM_TYPE));
// POST the request
try{
ClientResponse response = service.type("multipart/mixed").post(ClientResponse.class, multiPart);
System.out.println("Response Status : " + response.getEntity(String.class));
}catch(Exception e){
e.printStackTrace();
}
и в веб-сервисе:
@POST
@Consumes("multipart/mixed")
@Path("/upload")
public Response post(MultiPart multiPart) {
BodyPartEntity bpe = (BodyPartEntity) multiPart.getBodyParts().get(0)
.getEntity();
boolean isProcessed = false;
String message = null;
try {
InputStream source = bpe.getInputStream();
BufferedImage bi = ImageIO.read(source);
File file = new File("E:/Goodies/tmp" + "123.jpg");
// storing the image to file system.
if (file.isDirectory()) {
ImageIO.write(bi, "jpg", file);
} else {
file.mkdirs();
ImageIO.write(bi, "jpg", file);
}
isProcessed = true;
} catch (Exception e) {
message = e.getMessage();
}
Есть несколько вещей, которые нужно проверить
добавьте mimepull.jar в вашу библиотеку или с Maven
`<dependency>
<groupId>org.jvnet.mimepull</groupId>
<artifactId>mimepull</artifactId>
<version>1.9.5</version>
</dependency>`
И если вы работаете с файлом, убедитесь, что вы отправили в заголовке контент-тип контента accept-encoding
Вот моя работа вокруг:
WebResource webResource =
jerseyClient.resource("www.api.com");
WebResource.Builder requestBuilder = webResource.getRequestBuilder();
requestBuilder.header("content-type", "application/json");
ClientResponse response = requestBuilder
.post(ClientResponse.class, mObjectMapper.writeValueAsString(new RequestObject(longUrl)));
String text = response.getEntity(String.class);
ResponseObject outcome = mObjectMapper.readValue(text, ResponseObject.class);
Я использовал Джексон ObjectMapper
сериализовать полезную нагрузку запроса и десериализовать результат в ResponseObject
пример использования ObjectMapper
,
Я добавил это в web.xml
, Задача решена.
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>