Spring integration with Spring boot 1.4.0. Getting error - spring-boot

I upgraded from Spring boot 1.2.3 to 1.4.0 alongwith dependencies for Spring integration i.e. 4.3.1
I'm sending JSON content but getting an error on request submit. Previously it was working fine with Spring boot 1.2.3 and spring integration 4.1.2
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ws</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-xml</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<int-http:inbound-gateway id="controller" request-channel="requestChannel" reply-channel="responseChannel" path="/services/test"
supported-methods="POST" request-payload-type="com.example.SampleRequest" >
<int-http:request-mapping consumes="application/json"
produces="application/json" />
</int-http:inbound-gateway>
public class SampleRequest {
private String requestType;
private String reference;
private String nicNumber;
}
Error :
2016-12-20 15:06:14 [http-nio-8080-exec-1] DEBUG o.s.w.t.h.WebServiceMessageReceiverHandlerAdapter : Accepting incoming [org.springframework.ws.transport.http.HttpServletConnection#74518c78] at [http://localhost:8080/services/test]
2016-12-20 15:06:14 [http-nio-8080-exec-1] ERROR c.s.xml.internal.messaging.saaj.soap : SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
2016-12-20 15:06:14 [http-nio-8080-exec-1] DEBUG o.s.w.t.h.MessageDispatcherServlet : Could not complete request
org.springframework.ws.soap.SoapMessageCreationException: Could not create message from InputStream: Invalid Content-Type:application/json. Is this an error message instead of a SOAP response?; nested exception is com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:application/json. Is this an error message instead of a SOAP response?
at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:216)
at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:60)
at org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:92)
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:87)
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:61)
at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:293)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:application/json. Is this an error message instead of a SOAP response?
at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.identifyContentType(MessageImpl.java:655)
at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.<init>(MessageImpl.java:301)
at com.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl.<init>(Message1_1Impl.java:65)
at com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl.createMessage(SOAPMessageFactory1_1Impl.java:63)

Spring boot 1.2.3 didn't have WebService (SOAP) support. Right now we have WebServicesAutoConfiguration since 1.4.0. There you can find this code:
String path = this.properties.getPath();
String urlMapping = (path.endsWith("/") ? path + "*" : path + "/*");
ServletRegistrationBean registration = new ServletRegistrationBean(servlet,
urlMapping);
Where you bump unexpected default in the WebServicesProperties:
#NotNull
#Pattern(regexp = "/[^?#]*", message = "Path must start with /")
private String path = "/services";
So, that newly created MessageDispatcherServlet intercepts all your requests because you expect them on the path="/services/test".
If you are not interested in the SOAP server side in your application you can just exclude WebServicesAutoConfiguration from auto-configuration.
Otherwise consider to change your service URL or specify something another for the spring.webservices.path application property.

Related

Use LocalDateTime wirh Spring Boot and Gson

I have a simple maven project for generating a rest client with openapi-generator-maven-plugin from an open-api json file.
I'm using <library>okhttp-gson</library> and because I don't want to use OffsetDateTime I'm also using <dateLibrary>java8-localdatetime</dateLibrary>
To build the generated sources I'm using those dependencies
<properties>
<gson-version>2.10</gson-version>
<gson-fire-version>1.8.5</gson-fire-version>
<okhttp3-version>4.10.0</okhttp3-version>
<swagger-version>1.6.8</swagger-version>
</properties>
<dependencies>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-version}</version>
</dependency>
<!-- #Nullable annotation -->
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
</dependency>
<!-- HTTP client : okhttp3 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${okhttp3-version}</version>
</dependency>
<!-- JSON processing : gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10</version>
</dependency>
<dependency>
<groupId>io.gsonfire</groupId>
<artifactId>gson-fire</artifactId>
<version>${gson-fire-version}</version>
</dependency>
</dependencies>
Next to that I have a Spring Boot project for using the client.
<dependency>
<groupId>com.example</groupId>
<artifactId>demo-api-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
The problem is that when I'm using the client I have
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.time.LocalDate java.time.LocalDateTime.date accessible: module java.base does not "opens java.time" to unnamed module #562ff1d6
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[na:na]
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[na:na]
...
I read somewhere to add
#Configuration
public class GsonConfiguration {
#Bean
public GsonBuilderCustomizer typeAdapterRegistration() {
System.out.println("---typeAdapterRegistration");
return builder -> {
builder.registerTypeAdapter(LocalDateTimeDeserializer.class, new LocalDateTimeDeserializer());
};
}
}
and
public class LocalDateTimeDeserializer implements JsonDeserializer<LocalDateTime> {
#Override
public LocalDateTime deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
System.out.println("---deserialize");
return LocalDateTime.parse(jsonElement.getAsString(), DateTimeFormatter.ISO_LOCAL_DATE);
}
}
But is not not working. typeAdapterRegistration is excuted but not deserialize.
How can I do ?
Most likely the following line is causing the issue:
builder.registerTypeAdapter(LocalDateTimeDeserializer.class, new LocalDateTimeDeserializer())
Here you are registering the deserializer for type LocalDateTimeDeserializer, but you don't want to deserialize a LocalDateTimeDeserializer, you want to deserialize a LocalDateTime, so it should be:
builder.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeDeserializer())

SpringBoot SOAP Service: SAAJ SOAP message has no body

I have a SOAP webservice built from wsdl, with Springboot, version 2.5.2, cxf version 3.4.4
I have built a service with cxf alone and it works like a charm and I want to use Spring to build the service.
Please find below the code:
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "Update")
#SoapAction("http://www.sample.edu/XXPath/IDM/XXIDMService/Update")
#ResponsePayload
public JAXBElement<XXPathServiceResponseType> update
(#RequestPayload UpdateType request,
MessageContext context) throws Exception {
XXPathServiceResponseType resp = new ObjectFactory().createXXPathServiceResponseType();
resp.setCorrelationId(request.getCorrelationId());
QName qname = new QName("http://www.sample.edu/XXPath",
"XXPathServiceResponse");
return new JAXBElement<>(qname, XXPathServiceResponseType.class, resp);
}
I have enabled the message validation and securement actions (Timestamp Signature Encrypt)
Below is my pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<!-- end::dependency[] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
</dependency>
</dependencies>
On hitting the service, I get the error:
2021-07-22 21:43:39.612 ERROR 19061 --- [-nio-443-exec-6] a.c.c.C.[.[.[.[messageDispatcherServlet] : Servlet.service() for servlet [messageDispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.ws.soap.saaj.SaajSoapBodyException: SAAJ SOAP message has no body] with root cause
org.springframework.ws.soap.saaj.SaajSoapBodyException: SAAJ SOAP message has no body
at org.springframework.ws.soap.saaj.SaajSoapEnvelope.getBody(SaajSoapEnvelope.java:54) ~[spring-ws-core-3.1.1.jar:na]
at org.springframework.ws.soap.AbstractSoapMessage.getSoapBody(AbstractSoapMessage.java:38) ~[spring-ws-core-3.1.1.jar:na]
at org.springframework.ws.soap.AbstractSoapMessage.hasFault(AbstractSoapMessage.java:62) ~[spring-ws-core-3.1.1.jar:na]
at org.springframework.ws.soap.AbstractSoapMessage.getFaultCode(AbstractSoapMessage.java:68) ~[spring-ws-core-3.1.1.jar:na]
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:94) ~[spring-ws-core-3.1.1.jar:na]
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:60) ~[spring-ws-core-3.1.1.jar:na]
at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:288) ~[spring-ws-core-3.1.1.jar:na]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665) ~[javax.servlet-api-4.0.1.jar:4.0.1]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750) ~[javax.servlet-api-4.0.1.jar:4.0.1]
Please help me with this error.
Thanks,
Ravi.
Found a solution, in case if it helps
While encrypting, I have specified the encryption parts (Body and Timestamp) that's what breaking this.
I have removed the setter in the interceptor
securityInterceptor.setSecurementEncryptionParts();
For some reason, Spring is taking SAAJ and is not attaching the response I have set in the endpoint to SAAJ body and the encryption is failing

How to setup Swagger with Spring Boot Camel for REST messaging

I'm following Swagger Java example, but can't make it work with Spring Boot Camel.
I'm running Spring Boot Camel 3.4.0, and have next dependencies in pom.xml:
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Camel -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-stream-starter</artifactId>
</dependency>
<!-- REST -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-rest-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-servlet-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jackson-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jaxb-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-netty-http-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-http-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jetty-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-undertow-starter</artifactId>
</dependency>
<!--<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-rest-swagger-starter</artifactId>
</dependency>-->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-swagger-java</artifactId>
<version>3.4.0</version>
</dependency>
My Router.java is next:
String listenAddress = "192.168.0.100";
int listenPort = 8080;
restConfiguration()
.component("netty-http")
.scheme("http")
.host(listenAddress)
.bindingMode(RestBindingMode.auto)
.dataFormatProperty("prettyPrint", "true")
.port(listenPort)
.contextPath("/")
// add swagger api-doc out of the box
.apiContextPath("/api-doc")
.apiProperty("api.title", "User API").apiProperty("api.version", "1.2.3")
// and enable CORS
.apiProperty("cors", "true");
// this user REST service is json only
rest("/user").description("User rest service")
.consumes("application/json").produces("application/json")
.get("/{id}").description("Find user by id").outType(User.class)
.param().name("id").type(path).description("The id of the user to get").dataType("int").endParam()
.log("Swagger REST header id: ${header.id}");
If trying to GET http://192.168.0.100:8080/api-doc I'm getting 404.
This route above should print log in Camel terminal when using REST GET with http://192.168.0.100:8080/user/123 or am I wrong? Can't see what's missing.
The context path by default is set to /camel/, which means if rest of your configuration is correct, you should be able to see your api-docs at http://192.168.0.100:8080/camel/api-doc
To override it, you need to set the following property in your application.properties file.
camel.component.servlet.mapping.context-path= /*
For me adding the configuration :
In routes
String listenAddress = "localhost";
int listenPort = 8003;
restConfiguration()
.component("servlet")
.scheme("http")
.host(listenAddress)
.bindingMode(RestBindingMode.auto)
.dataFormatProperty("prettyPrint", "true")
.port(listenPort)
.contextPath("/")
// add swagger api-doc out of the box
.apiContextPath("/api-doc")
.apiProperty("api.title", "User API").apiProperty("api.version", "1.2.3")
// and enable CORS
.apiProperty("cors", "true");
In application.properties
server.port=8003
camel.component.servlet.mapping.context-path=/**
URI
http://localhost:8003/api-doc
I am using camel version : 3.9.0
This solution works fine !!!!

MultipartFormDataInput error when using java spring boot

I am using Angular 8 for front-end and Java Spring boot for back-end and on submit button the formdata along with a file attached in the form should post to the server. But I am getting an error at the backend when I click on the submit button as this-
2020-01-16 10:09:20.317 ERROR 4764 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput] with root cause
java.lang.NoSuchMethodException: org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput.<init>()
Front-end code snippet:
createMaintenanceRequest(data: FormData): Observable<any> {
return this.http.post(this.MAINTENANCE_URL, data,{headers: this.HEADERS})
.map(this.extractData)
.catch(err => this.handleError(err));
}
Back-end code snippet:
#CrossOrigin(origins = "*")
#RequestMapping(value="/api/maintenance",method= RequestMethod.POST)
#ResponseBody
#Consumes(javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA)
public Response postMaintenanceRequest ( MultipartFormDataInput maintenanceData) throws IOException
{
System.out.println("postMaintenanceRequest - ENTER");
MaintenanceService maintenanceService = MaintenanceService.getInstance();
ServiceResponse serviceResponse = maintenanceService.createMaintenanceStory(maintenanceData);
Response response;
switch (serviceResponse.getServiceOutcome())
{
case SUCCESS:
JsonObject payload = new JsonObject();
JsonObject data = new JsonObject();
data.addProperty("url", serviceResponse.getStoryURL());
System.out.println("postIncident responding with story url: " + serviceResponse.getStoryURL());
payload.add("data", data);
response = Response.ok(payload.toString()).build();
break;
case INVALID_DATA:
response = Response.status(Response.Status.BAD_REQUEST).build();
break;
case RALLY_ERROR:
default:
response = Response.serverError().build();
break;
}
This is my pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.hello</groupId> <!--com.test.hello.firstone-->
<artifactId>DashboardService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<name>DashboardService</name>
<description>Spring Boot base web application</description>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<start-class>com.test.si.main.Main</start-class>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
<version>0.0.20131108.vaadin1</version>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.rallydev.rest</groupId>
<artifactId>rally-rest-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>3.9.3.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
MultipartFormDataInput is resteasy (jboss) api and will not work with tomcat servlet container. Either use spring (as someone suggested) or use jersey one.
In spring change your controller method to
#RequestMapping(value="/api/maintenance",method= RequestMethod.POST
postMaintenanceRequest(#RequestParam("file") MultipartFile file) {
.....
.....
}
In your front be sure that you put the file like that
formData = new FormData();
formData.append('file', myFileData);
If you don't have authorization data on your header, dont create a custom header, angular will do it for you

Keycloak admin-client: Unable to find a MessageBodyReader of content-type application/json

I'm new to keycloak and spring. I'm trying to use the keycloak admin-client to create a user in my spring-boot project like this:
Keycloak kc = Keycloak.getInstance(
"http://localhost:8080/auth",
"master", // the realm to log in to
"admin", "password", // the user
"admin-cli");
CredentialRepresentation credential = new CredentialRepresentation();
credential.setType(CredentialRepresentation.PASSWORD);
credential.setValue("test123");
UserRepresentation user = new UserRepresentation();
user.setUsername("testuser");
user.setFirstName("Test");
user.setLastName("User");
user.setCredentials(Arrays.asList(credential));
kc.realm("master").users().create(user);
but I keep getting this error:
Exception in thread "main" javax.ws.rs.client.ResponseProcessingException: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type application/json and type class org.keycloak.representations.AccessTokenResponse
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:158)
at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:60)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:107)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy18.grantToken(Unknown Source)
at org.keycloak.admin.client.token.TokenManager.grantToken(TokenManager.java:89)
at org.keycloak.admin.client.token.TokenManager.getAccessToken(TokenManager.java:69)
at org.keycloak.admin.client.token.TokenManager.getAccessTokenString(TokenManager.java:64)
at org.keycloak.admin.client.resource.BearerAuthFilter.filter(BearerAuthFilter.java:52)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:443)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:105)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy26.create(Unknown Source)
at me.phuongtm.KeycloakAdminClientDemoApplication.main(KeycloakAdminClientDemoApplication.java:68)
Caused by: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type application/json and type class org.keycloak.representations.AccessTokenResponse
at org.jboss.resteasy.core.interception.jaxrs.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:42)
at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:80)
at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:53)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:266)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readEntity(ClientResponse.java:196)
at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:212)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:122)
... 13 more
It seems to be a problem with RESTEASY, so I added resteasy-jackson2-provider as suggested by keycloak docs, but no luck.
Here are my pom.xml dependecies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>3.2.0.Final</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.1.4.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>3.1.4.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>3.1.4.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
I spent hours and hours trying to find an answer, I even tried this MatteoM's solution:
https://stackoverflow.com/a/40462534/7441720
But no luck.
I appreciate all the help I can get
UPDATE:
It appears to be an issue of providers:
10:06:45.027 [main] WARN org.jboss.resteasy.resteasy_jaxrs.i18n -
RESTEASY002145: NoClassDefFoundError: Unable to load builtin provider
org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider from
jar:file:/C:/Users/hp/.m2/repository/org/jboss/resteasy/resteasy-jackson2-
provider/3.1.4.Final/resteasy-jackson2-provider-3.1.4.Final.jar!/META-
INF/services/javax.ws.rs.ext.Providers
I can't seem to find a solution, I checked the jar and the class
ResteasyJackson2Provider
exists!
UPDATE:
From what I can tell, it was an issue with dependecies, I switched to gradle (but it should work for maven as well), my new dependencies are:
compile('org.keycloak:keycloak-admin-client:3.2.1.Final')
compile('org.jboss.resteasy:resteasy-client:3.0.14.Final')
compile('org.jboss.resteasy:resteasy-multipart-provider:3.0.14.Final')
compile('org.jboss.resteasy:resteasy-jackson2-provider:3.0.14.Final')
compile('org.jboss.resteasy:resteasy-jaxb-provider:3.0.14.Final')
compile('org.jboss.resteasy:resteasy-jettison-provider:3.0.14.Final')
compile('org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.0_spec:1.0.0.Final')
As for keycloak, I created a Configuration class with a bean:
#Bean
public Keycloak keycloakBeanConfig(){
return KeycloakBuilder.builder().serverUrl(keycloakUrl).realm(realm) //
.grantType(OAuth2Constants.CLIENT_CREDENTIALS).clientId(clientId) //
.clientSecret(clientSecret)
.build();
}
try to use resteasy-jackson-provider and removeresteasy-jackson2-provider. you can find dependency below:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.1.3.Final</version>
</dependency>

Resources