Producing SOAP webservices with spring-ws with Soap v1.2 instead of the default v1.1 - soap

I am currently working on Spring soap server project. I started off with the Getting Started guide from Spring here http://spring.io/guides/gs/producing-web-service/ to build a basic SOAP service.
The default SOAP protocol is SOAP v1.1. Is there a way I could set the protocol to v1.2, possibly via annotations?
I tried #BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING) annotation on the #Endpoint class but it doesnt seem to work.
I also tried #Endpoint(value = SOAPBinding.SOAP12HTTP_BINDING) to set it, but this doesnt work either as seen in the logs on startup
INFO --- [nio-8080-exec-1] o.s.ws.soap.saaj.SaajSoapMessageFactory :
Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
Ofcourse, if I post a SOAP request to the server, I get the following error
2015-01-19 15:50:17.610 ERROR 20172 --- [nio-8080-exec-1] c.sun.xml.internal.messaging.saaj.soap : SAAJ0533: Cannot create message: incorrect content-type for SOAP version. Got application/soap+xml;
charset=utf-8, but expected text/xml
2015-01-19 15:50:17.611 ERROR 20172 --- [nio-8080-exec-1] c.sun.xml.internal.messaging.saaj.soap :
SAAJ0535: Unable to internalize message
2015-01-19 15:50:17.617 ERROR 20172 --- [nio-8080-exec-1] a.c.c.C.[.[.[.[messageDispatcherServlet] :
Servlet.service() for servlet [messageDispatcherServlet] in context with path [] threw exception [R
equest processing failed; nested exception is org.springframework.ws.soap.SoapMessageCreationException: Could not create message from InputStream: Unable to internalize message; nested exception is com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to internalize message] with root cause
com.sun.xml.internal.messaging.saaj.soap.SOAPVersionMismatchException: Cannot create message: incorrect content-type for SOAP version. Got: application/soap+xml; charset=utf-8 Expected: text/xml
at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.init(Unknown Source)
at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.<init>(Unknown Source)
at com.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl.<init>(Unknown Source)
at com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl.createMessage(Unknown Source)
Any help is appreciated.
Thanks!

You are mixing Spring-WS with annotations from JAX-WS (package javax.xml.ws). That won't work. To configure Spring-WS to use SOAP 1.2, add the following bean definition:
#Bean
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
return messageFactory;
}

If the messageFactory Bean is not in the singleton scope, then the afterPropertiesSet() method in the SaajSoapMessageFactory is not called on bean instantation.
The afterPropertiesSet() method sets up an internal message factory. So if your messageFactory bean has its own scope you need to set up the internal message factory like this:
#Bean
#Scope("custom-scope")
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
return messageFactory;
}

The messageFactory() #Bean is a necessary step, but isn't it also fundamental to add
wsdl11Definition.setCreateSoap12Binding(true);
to the service definition, to generate the appropriate soap 1.2 binding?
Anyway, thanks to Andreas Veithen

Related

RMI using spring. Executing method in server with object as parameter

I am trying to execute a method from client to server using RMI.
As long as the parameters are String, it is getting executed correctly. If I am using object as method parameter.
I am getting following exception :
java.rmi.UnmarshalException: Error unmarshaling return; nested exception is:
java.lang.ClassNotFoundException: org.eclipse.persistence.exceptions.DatabaseException (no security manager: RMI class loader disabled)
Server configuration:
#Bean
public RmiServiceExporter getUserService() {
RmiServiceExporter exporter = new RmiServiceExporter();
exporter.setService(userService);
exporter.setServiceName("UserService");
exporter.setServiceInterface(UserService.class);
exporter.setRegistryPort(1192);
exporter.setReplaceExistingBinding(true);
return exporter;
}
Client configuration:
public #Bean RmiProxyFactoryBean getUserService() {
RmiProxyFactoryBean rmi = new RmiProxyFactoryBean();
rmi.setServiceInterface(UserService.class);
rmi.setServiceUrl("rmi://localhost:1192/UserService");
return rmi;
}
Test code :
User user = userService.getUser(String userName);
Works perfectly fine.
userService.save(user);
Save user throws RMI exception.
I made sure that the package name for User object in server and client is same. Still I am getting the exception.
Am I missing any configuration? How can I make RMI server to load the other classes?

Message body reader for AsyncResponse

I'm using async reposne feature of jersey in my resource
#GET
#Path("/{a}")
#Produces(Array(MediaType.APPLICATION_XML))
def asyncGet(#Suspended asyncResponse: AsyncResponse, #PathParam("a") a: Int): Unit = {
someFuture.onSuccess(asyncResponse.resume(_))
}
But when performing request to this resource I get
SEVERE: A message body reader for Java class javax.ws.rs.container.AsyncResponse, and Java type interface javax.ws.rs.container.AsyncResponse, and MIME media type application/octet-stream was not found
I'm using grizzly as http server
The problem was in one custom library that transitivly was depended on jersey 1.x, but I'm using jersey 2.x in my project. So the problem solved

JAX RS 500 Error

I have a pretty simple service that is returning a 500 error - here's the details on the error:
[EL Info]: 2013-11-01 11:09:05.61--ServerSession(741529784)--EclipseLink, version: Eclipse Persistence Services - 2.3.2.v20111125-r10461
[EL Info]: 2013-11-01 11:09:06.452--ServerSession(741529784)--file:/C:/Users/Fred/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/cheese-ws/WEB-INF/lib/cheese-jpa.jar_cheese login successful
34442 [http-bio-8080-exec-1] ERROR org.apache.wink.server.internal.handlers.FlushResultHandler - The system could not find a javax.ws.rs.ext.MessageBodyWriter or a DataSourceProvider class for the java.util.Vector type and application/json mediaType. Ensure that a javax.ws.rs.ext.MessageBodyWriter exists in the JAX-RS application for the type and media type specified.
34446 [http-bio-8080-exec-1] INFO org.apache.wink.server.internal.RequestProcessor - The following error occurred during the invocation of the handlers chain: WebApplicationException (500 - Internal Server Error) with message 'null' while processing GET request sent to ...
The code is pretty straightforward and very similar to other services that work fine:
public class StudentTeacherCommunicationService extends BaseService {
#GET
#Path("classroomId/{classroomId}/studentId/{studentId}")
#Produces(MediaType.APPLICATION_JSON)
public List<ClassroomStudentCommunication> getCandidatesAsJson(#PathParam("classroomId") int classroomId, #PathParam("studentId") int studentId) {
EntityManager em = createEM();
TypedQuery<ClassroomStudentCommunication> query;
if(studentId==0) {
query = em.createQuery("SELECT csc FROM ClassroomStudentCommunication csc where csc.classroomId = :classroomId ORDER BY csc.threadOrder", ClassroomStudentCommunication.class);
query.setParameter("classroomId", classroomId);
List <ClassroomStudentCommunication> classCommunication = query.getResultList();
return classCommunication;
Any ideas?
This seems to be a Rest problem not a JPA problem.
If you happen to use Maven and generated the project with an archetype or IDE, it is worth to check the generated pom.xml. JSON support can be turned off by default in the pom.xml.
For example if you use Jersey and your project is generated with jersey-quickstart-webapp archetype then you should uncomment the following section manually in the pom.xml:
<!-- uncomment this to get JSON support
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
-->

soap client with cxf: Soap11FaultInInterceptor.unmarshalFault

I am developing a SOAP client with Apache CXF. One method of the request returns me this stack in the client. With SOAPUI the same request returns me the expected response. Maybe I lost a library in JNLP? Maybe it is a binding problem?
2013-11-08 15:31:16,593 ERROR [es.isoftsanidad.eprescribe.comunclient.paneles.buscadorfarmacos.ListadoPF5Controlador] [setListaObjetos] Error en establecer el listado de los objetos
javax.xml.ws.soap.SOAPFaultException: Couldn't create SOAP message due to exception: Unable to create StAX reader or writer
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:157)
at
.....
Caused by: org.apache.cxf.binding.soap.SoapFault: Couldn't create SOAP message due to exception: Unable to create StAX reader or writer
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:84)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:51)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:40)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:140)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:71)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:835)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1606)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1502)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1309)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:627)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
Check the logs on the server side. This is the message that the server is sending back in it's SOAP fault. Thus, something is happening on the server side that needs investigating.

Log4j Initialization error JBoss RestEasy

I am using JBoss 6.0. I am running a simple webserver using the jboss.resteasy library to provide simple XML responses to HTTP requests.
I have:
- A server
- A simple Java Client that creates a GET request
Now the thing is, if I use the browser to access the URL, I get the wanted XML. But if I use my Java client, which has the following code:
//Register the fake instrument
GetMethod get = new GetMethod("http:/localhost:8080/"+PROJECT_NAME+"/webserver/registerInstrument/?name=FakeClient&value=0");
HttpClient client = new HttpClient();
try {
int status = client.executeMethod(get);
} catch (HttpException e) {
System.out.println("[FakeClient] HttpException executing AddInstrument GET request: "+e);
} catch (IOException e) {
System.out.println("[FakeClient] IOException executing AddInstrument GET request: "+e);
}
Then I get the following exception:
log4j:WARN No appenders could be found for logger (org.apache.commons.httpclient.params.DefaultHttpParams).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.IllegalArgumentException: Host name may not be null
at org.apache.commons.httpclient.HttpHost.<init>(HttpHost.java:68)
at org.apache.commons.httpclient.HttpHost.<init>(HttpHost.java:107)
at org.apache.commons.httpclient.HttpMethodBase.setURI(HttpMethodBase.java:280)
at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:220)
at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89)
at client.FakeClient.<init>(FakeClient.java:30)
at client.FakeClient.main(FakeClient.java:22)
At first I thought this could be a problem with the JBoss logging, but if I access the URL through the browser, I obtain the desired XML with no problems.
Is this a problem with the Java client application?
Thank you
The 'log4j:WARN' is just a warning. It has nothing do to with the actual exception being thrown.
The exception message states that 'Host name may not be null'. This clearly indicates that there is something wrong the the hostname. And looking at you code, I can spot one error.
You need to add an extra forward slash:
GetMethod get = new GetMethod("http://localhost:8080/" ...