javax.ws.rs.ProcessingException, не удалось найти писатель для приложения типа содержимого / типа json в Payara Server 5
Первый Sorry for my bulky source code and simple question.
Я получаю эту ошибку.
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
Использование Postman с URL http: // localhost:8080 / api / v1 / customers / createPurchaser
Мой 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("john.mason@mail.com");
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;
}
}
В Customer
класс
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
}
В Purchaser
класс
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;
}
}
1 ответ
Проблема в том jersey-client
зависимость. Вам нужно его удалить. Причина: общийClientBuilder
будет построен, чтобы всегда статьJerseyClientBuilder
когда клиент Джерси находится на пути к классам. Имеющаяся у вас зависимость JSON (которая автоматически регистрируется в клиенте RESTEast)resteasy-jackson2-provider
для RESTEasy. Таким образом, клиент из Джерси не узнает этого. Вы можете вручную зарегистрировать провайдера у клиента, и он должен работать.
client.register(JacksonJaxbJsonProvider.class);
Но, как я уже сказал, просто удали jersey-client
а также ClientBuilder
станет ResteasyClientBuilder
и он распознает resteasy-jackson2-provider
и автоматически зарегистрируйте его. Если ваша цель - использовать клиент Джерси, в этом случае вам необходимо вручную зарегистрировать поставщика или добавить зависимость автоматической регистрации Джерси, которая являетсяjersey-media-json-jackson
.
Обновить
Обратите внимание: если вы планируете использовать клиент в серверной среде, я только что заметил, что вы используете Payara, который использует Jersey под капотом. Таким образом, сервер уже оснащен всеми банками Джерси. Если вы хотите использовать Джексона в качестве провайдера, вам следует добавитьjersey-media-json-jackson
и зарегистрируйте JacksonFeature
с клиентом. Если вы этого не сделаете, по умолчанию будет использоваться JSONB в качестве поставщика JSON. Если вы хотите использовать RESTEasy, то можете забыть об этом.