java - javax.ws.rs.ProcessingException、Payara Server 5 でコンテンツ タイプ アプリケーション/json タイプのライターが見つかりませんでした

okwaves2024-01-25  10

まず、分厚いソースコードと単純な質問で申し訳ありません。

このエラーが発生します。

javax.ws.rs.ProcessingException: RESTEASY003215: コンテンツ タイプ アプリケーション/json タイプのライターが見つかりませんでした: com.acme.customers.lib.v1.Customer

完全なトレース:

--- exec-maven-plugin:1.5.0:exec (default-cli) @ acme-customers-api ---
Exception in thread "main" javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: javax.ws.rs.ProcessingException: RESTEASY003215: could not find writer for content-type application/json type: com.acme.customers.lib.v1.Customer
    at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.invoke(ManualClosingApacheHttpClient43Engine.java:287)
    at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:488)
    at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:65)
    at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.post(ClientInvocationBuilder.java:226)
    at com.acme.customers.api.rest.v1.test.ConsumingServices.main(ConsumingServices.java:67)
Caused by: javax.ws.rs.ProcessingException: RESTEASY003215: could not find writer for content-type application/json type: com.acme.customers.lib.v1.Customer
    at org.jboss.resteasy.core.interception.jaxrs.ClientWriterInterceptorContext.throwWriterNotFoundException(ClientWriterInterceptorContext.java:50)
    at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.getWriter(AbstractWriterInterceptorContext.java:302)
    at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.syncProceed(AbstractWriterInterceptorContext.java:240)
    at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:224)
    at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.writeRequestBody(ClientInvocation.java:440)
    at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.writeRequestBodyToOutputStream(ManualClosingApacheHttpClient43Engine.java:589)
    at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.buildEntity(ManualClosingApacheHttpClient43Engine.java:548)
    at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.loadHttpMethod(ManualClosingApacheHttpClient43Engine.java:455)
    at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.invoke(ManualClosingApacheHttpClient43Engine.java:265)
    ... 4 more
Command execution failed.
org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
    at org.apache.commons.exec.DefaultExecutor.executeInternal (DefaultExecutor.java:404)
    at org.apache.commons.exec.DefaultExecutor.execute (DefaultExecutor.java:166)
    at org.codehaus.mojo.exec.ExecMojo.executeCommandLine (ExecMojo.java:764)
    at org.codehaus.mojo.exec.ExecMojo.executeCommandLine (ExecMojo.java:711)
    at org.codehaus.mojo.exec.ExecMojo.execute (ExecMojo.java:289)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)


------------------------



------------------------

BUILD FAILURE

------------------------



------------------------

Total time: 5.277 s Finished at: 2020-09-03T10:55:26-05:00

------------------------



------------------------

Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.5.0:exec (default-cli) on project acme-customers-api: Command execution failed.: Process exited with an error: 1 (Exit value: 1) -> [Help 1] To see the full stack trace of the errors, re-run Maven with the -e switch. Re-run Maven using the -X switch to enable full debug logging. For more information about the errors and possible solutions, please read the following articles: [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

URL http://localhost:8080/api/v1/customers/createPurchaser で Postman を使用する

ヘッダーあり

私の ConsumingServices クラスは

import java.util.Date;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;

public class ConsumingServices {

    public static void main(String[] args) {
        Customer customer = new Customer();
        customer.setFirstName("John");
        customer.setLastName("Mason");
        customer.setEmail("[email protected]");
        customer.setDateOfBirth(new Date());
        customer.setStatus(CustomerStatus.ACTIVE);

        ClientConfig configuration = new ClientConfig();
        configuration.property(ClientProperties.CONNECT_TIMEOUT, 1000);
        configuration.property(ClientProperties.READ_TIMEOUT, 1000);
        Client client = ClientBuilder.newClient(configuration);

        WebTarget target = client.target("http://localhost:8080/api/v1/customers");

        Invocation.Builder invocationBuilder = target.path("createPurchaser")
                .request(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON);

        Response response = invocationBuilder
                .header("Authorization", "1234")
                .post(Entity.entity(customer, MediaType.APPLICATION_JSON));

        if (response.getStatus() == Response.Status.OK.getStatusCode()) {
            Purchaser purchaser = response.readEntity(Purchaser.class);
            System.out.println("purchaser:".concat(purchaser.toString()));
        } else {
            if (MediaType.TEXT_PLAIN_TYPE.equals(response.getMediaType())) {
                String message = response.readEntity(String.class);
                System.out.println("message:" + message);
            } else if (MediaType.APPLICATION_JSON.equals(response.getMediaType())) {
                ApiError apiError = response.readEntity(ApiError.class);
                System.out.println("apiError:".concat(apiError.toString()));
            } else {
                System.out.println("response.getMediaType():" + response.getMediaType());
                String content = response.readEntity(String.class);
                System.out.println("message:" + content);
            }
        }
    }
}

例外のある行は .post(Entity.entity(customer, MediaType.APPLICATION_JSON));

pom.xml 内の依存関係は次のとおりです

<dependencies>
    <dependency>
        <groupId>com.acme</groupId>
        <artifactId>acme-customers-lib</artifactId>
        <version>${project.version}</version>
    </dependency>

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
    </dependency>
    
    <dependency>
        <groupId>fish.payara.extras</groupId>
        <artifactId>payara-embedded-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax/javaee-web-api -->
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>8.0.1</version>
        <scope>provided</scope>
    </dependency>
    
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-client -->
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.31</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.jboss.resteasy/jaxrs-api -->
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>jaxrs-api</artifactId>
        <version>3.0.12.Final</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-client -->
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>4.5.6.Final</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jaxrs -->
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>3.13.0.Final</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jaxb-provider -->
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxb-provider</artifactId>
        <version>4.5.6.Final</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jackson2-provider -->
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jackson2-provider</artifactId>
        <version>4.5.6.Final</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.11.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.1</version>
    </dependency>

</dependencies>

質問: この例外を修正するにはどうすればよいですか?

私のクラスのコード....

CustomerResource クラス

@Path("/customers")
@ApplicationScoped
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class CustomerResource {
    @POST
    @Path("/createPurchaser")
    public Response createPurchaser(Customer customer) {
        return Response
            .status(Response.Status.OK)
            .entity(customerService.createPurchaser(customer))
            .type(MediaType.APPLICATION_JSON)
            .build();
    }
}

CustomerService インターフェイス

public interface CustomerService {

    Purchaser createPurchaser(Customer customer);
}

createPurchaser メソッドCustomerServiceImpl クラス

@ApplicationScoped
public class CustomerServiceImpl implements CustomerService {

    @Override
    public Purchaser createPurchaser(Customer customer) {

        if (customer == null) {
            throw new EmptyPayloadException(Customer.class.getSimpleName());
        }
        
        Purchaser client = new Purchaser();
        
        client.setFirstName(customer.getFirstName());
        client.setLastName(customer.getLastName());
        client.setAffiliationDate(new Date());
        client.setCustomerStatus(CustomerStatus.ACTIVE);
        client.setPurchaserDocument(new PurchaserDocument());
        client.getPurchaserDocument().setDateOfBirth(customer.getDateOfBirth());
        client.getPurchaserDocument().setNumberDocument(new Random().nextLong());
        client.getPurchaserDocument().setTypeDocument("CC");
        return client;
    }
}

顧客クラス

import java.io.Serializable;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Customer extends BaseType implements Serializable {

    private String firstName;
    private String lastName;
    private CustomerStatus status;
    private String email;
    private Date dateOfBirth;

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public CustomerStatus getStatus() {
        return status;
    }
    public void setStatus(CustomerStatus status) {
        this.status = status;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Date getDateOfBirth() {
        return dateOfBirth;
    }
    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }
}

今度は BaseType クラスです

import java.util.Date;
public class BaseType {

    private String id;
    private Date createdAt;
    private Date updatedAt;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public Date getCreatedAt() {
        return createdAt;
    }
    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }
    public Date getUpdatedAt() {
        return updatedAt;
    }
    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }
}

CustomerStatus 列挙型

public enum CustomerStatus {
    ACTIVE, INACTIVE
}

購入者クラス

import java.io.Serializable;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Purchaser implements Serializable {

    private String firstName;
    private String lastName;
    private Date affiliationDate;
    private CustomerStatus customerStatus;
    private PurchaserDocument purchaserDocument;

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Date getAffiliationDate() {
        return affiliationDate;
    }
    public void setAffiliationDate(Date affiliationDate) {
        this.affiliationDate = affiliationDate;
    }
    public CustomerStatus getCustomerStatus() {
        return customerStatus;
    }
    public void setCustomerStatus(CustomerStatus customerStatus) {
        this.customerStatus = customerStatus;
    }
    public PurchaserDocument getPurchaserDocument() {
        return purchaserDocument;
    }
    public void setPurchaserDocument(PurchaserDocument purchaserDocument) {
        this.purchaserDocument = purchaserDocument;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("Purchaser{firstName=").append(firstName);
        sb.append(", lastName=").append(lastName);
        sb.append(", affiliationDate=").append(affiliationDate);
        sb.append(", customerStatus=").append(customerStatus);
        sb.append(", purchaserDocument=").append(purchaserDocument);
        sb.append('}');
        return sb.toString();
    }
}

PurchaserDocument クラス

import java.io.Serializable;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class PurchaserDocument implements Serializable {

    private String typeDocument;
    private Long numberDocument;
    private Date dateOfBirth;

    public String getTypeDocument() {
        return typeDocument;
    }
    public void setTypeDocument(String typeDocument) {
        this.typeDocument = typeDocument;
    }
    public Long getNumberDocument() {
        return numberDocument;
    }
    public void setNumberDocument(Long numberDocument) {
        this.numberDocument = numberDocument;
    }
    public Date getDateOfBirth() {
        return dateOfBirth;
    }
    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

}


------------------------

問題は、ジャージとクライアントの依存関係です。それを取り除く必要があります。理由: 汎用 ClientBuilder は、Jersey クライアントがクラスパス上にある場合は常に JerseyClientBuilder になるように構築されています。持っている JSON 依存関係 (RESTEast クライアントに自動的に登録される)resteasy-jackson2-provider は RESTEasy 用です。そのため、Jersey クライアントはそれを認識しません。手動で登録することもできますプロバイダーをクライアントに接続すると、機能するはずです。

client.register(JacksonJaxbJsonProvider.class);

しかし、先ほども言いましたが、jersey-client を削除するだけで、ClientBuilder は ResteasyClientBuilder になり、resteasy-jackson2-provider を認識して自動的に登録されます。 Jersey クライアントを使用することが目的でない場合は、プロバイダーを手動で登録するか、Jersey 自動登録依存関係 (jersey-media-json-jackson) を追加する必要があります。

アップデート

サーバー環境でクライアントを使用する予定がある場合は、内部で Jersey を使用する Payara を使用していることに今気づきました。したがって、サーバーにはすべての Jersey jar がすでに装備されています。 Jackson をプロバイダーとして使用する場合は、jersey-media-json-jackson を追加し、JacksonFeature をクライアントに登録する必要があります。これをやらないと、デフォルトでは、JSONB を JSON プロバイダーとして使用します。 RESTEasy を使用したい場合は、これを忘れてかまいません。

4

ありがとうございます。しかし、ConsumingServices クラス (クライアント クラス) によると、 client.register(JacksonJaxbJsonProvider.class); はどのように行う必要がありますか?

– ホセルイスブス

2020 年 9 月 4 日 1:15

どこにいますかクライアントを参照してください?

– ポール・サムソサ

2020 年 9 月 4 日 1:18

理解していると思いますが、ConsumingServices クラス (クライアント クラス) を別の Maven プロジェクトのプロジェクトの外に置きます。

– ホセルイスブス

2020 年 9 月 4 日 1:21

あなたのことを理解できているかわかりません。そのクラスでは、Client client = ClientBuilder... これが呼び出す必要があるクライアントです。gister() がオンです。それが別のプロジェクトであるかどうかは、私にはまったくわかりません。私はあなたの投稿で示されている依存関係に基づいて答えています。

– ポール・サムソサ

2020 年 9 月 4 日 1:23

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。