Quarkus не смог найти писателя для клиента multipart-data-content / form-data rest

Я реализую API-шлюз для микросервиса отдыха с помощью Quarkus. Я хочу перенаправить запросы на другой (Quarkus) rest-api. Я пытаюсь переслать запрос POST с множественными данными. Я ожидаю получить 201, но получаю внутреннюю ошибку сервера 500. RESTEASY выдает следующую ошибку:

 RESTEASY002020: Unhandled asynchronous exception, sending back 500: javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: javax.ws.rs.ProcessingException: RESTEASY003215: could not find writer for content-type multipart/form-data type: org.acme.rest.client.multipart.MultipartBody

Я пробовал обновить свою версию Quarkus с 1.4.2 до 1.5.2, потому что увидел следующую проблему: https://github.com/quarkusio/quarkus/issues/8223

Также пробовал Intellij аннулировать кеш / перезапуск, повторно импортировать maven

Код

MultiPartBody:

package org.acme.rest.client.multipart;

import org.jboss.resteasy.annotations.providers.multipart.PartType;

import javax.ws.rs.FormParam;
import javax.ws.rs.core.MediaType;

public class MultipartBody {

    @FormParam("sample_id")
    @PartType(MediaType.TEXT_PLAIN)
    public Long sampleId;

    @FormParam("username")
    @PartType(MediaType.TEXT_PLAIN)
    public String username;

    @FormParam("content")
    @PartType(MediaType.TEXT_PLAIN)
    public String content;
}

Интерфейс:

package org.acme.rest.client;
import io.smallrye.mutiny.Uni;
import org.acme.rest.client.multipart.MultipartBody;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@RegisterRestClient
@Consumes(MediaType.MULTIPART_FORM_DATA)
public interface SocialService {

    @POST
    Uni<Response> create(@MultipartForm MultipartBody data);    

}

Ресурс:

package org.acme.rest.client;

import io.smallrye.mutiny.Uni;
import org.acme.rest.client.multipart.MultipartBody;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;

import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/comments")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public class SocialResource {

    @Inject
    @RestClient
    SocialService socialService;


    @POST
    public Uni<Response> create(@MultipartForm MultipartBody data) {
        return socialService.create(data);
    }

}

Тестовое задание:

package org.acme.rest.client;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;

@QuarkusTest
public class SocialResourceTest {

    @Test
    public void create(){
        given().contentType("multipart/form-data")
                .multiPart("sample_id", "1")
                .multiPart("username", "testuser")
                .multiPart("content", "test message")
                .when()
                .post("/comments")
                .then()
                .statusCode(201);
    }
}

person Hich    schedule 22.06.2020    source источник


Ответы (2)


Все выглядит нормально, но, возможно, вам не хватает этой зависимости

<dependency>
   <groupId>org.jboss.resteasy</groupId>
   <artifactId>resteasy-multipart-provider</artifactId>
</dependency>

Эта информация доступна в руководстве quarkus.

person Gerardo Arroyo    schedule 22.06.2020
comment
Зависимость также есть в POM. - person Hich; 23.06.2020

У меня была такая же проблема (не удалось найти писателя для multipart / form-data типа содержимого). Я решил это, расширив MultiPartBody MultipartFormDataOutput.

В вашем случае это будет:

...
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
...
public class MultipartBody extends MultipartFormDataOutput {
    ...
}

Я нашел это решение, посмотрев, как Quarkus / Resteasy внутренне разрешает записи вывода. Это делается в resolveMessageBodyWriter() методе org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl. Соответствующий автор - org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataWriter. Там метод isWriteable() проверяет, является ли MultipartFormDataOutput суперклассом вашего класса (MultipartBody).

Однако я не знаю, почему это работает без расширения MultipartFormDataOutput в примерах Quarkus.

Моя версия Quarkus - 1.8.2.Final, и я использую io.quarkus.quarkus-resteasy-multipart зависимость maven, а не org.jboss.resteasy.resteasy-multipart-provider.

person kvnb93    schedule 09.10.2020