I'm trying to get session in the jax-rs web service implementation class.After reading many forums i found out that in AX-WS SOAP-based web service we can use WebServiceContext to maintain the state.
#Resource
WebServiceContext wsContext;
#GET
#Produces("text/plain")
#Path("/hello")
public String hello() {
MessageContext mc = wsContext.getMessageContext(); !
ServletContext servletContext = (ServletContext)mc.get(MessageContext.SERVLET_CONTEXT);
...
}
Is there an equivalent approch in jax-rs REST_based webservice to handle an object state in the session or any other solution?
You need org.apache.cxf.jaxrs.ext.MessageContext
import javax.ws.rs.core.Context;
import org.apache.cxf.jaxrs.ext.MessageContext;
...
// add the attribute to your implementation
#Context
private MessageContext context;
...
// then you can access ServletContext in your methods
ServletContext ctx = context.getServletContext();
Related
i have a wsdl which is importing another wsdl in it.
i wanted to call the webservice from java client code, i have configured my java class as follows
package test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
#Configuration
public class WeConfig {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("test");
return marshaller;
}
#Bean
public WeatherClient1 weatherClient(Jaxb2Marshaller marshaller) {
WeatherClient1 client = new WeatherClient1();
client.setDefaultUri("*******");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
I have my acessing method as follows
GetDataResponse response = (GetDataResponse) getWebServiceTemplate()
.marshalSendAndReceive(
"*******",
request,
new SoapActionCallback("*******"));
My webservice would be something like
https://abcde.handling.com/celebrity/Confi?wsdl
Kindly let me know , what i have to input in setdefaultUri in configuration and soapcallbackaction. soap Ui gives me a method "GetData" for request
Thanks in advance..
Please help ..
After a long struggle , the answer for this query will be as follows;
DefaultUri = (Full WSDL) https://abcde.handling.com/celebrity/Confi?wsdl
there was no call back action for my request so:
GetDataResponse response = (GetDataResponse) getWebServiceTemplate()
.marshalSendAndReceive(
"Imported wsdl's URI",
request);
I am working currently on project where Apache CXF is integrated with Apache Camel. Apache CXF is a solution that we use to expose a WebService then marshal/unmarshal SOAP request and pass it to Camel. This is pretty standard. By default a POJO dataFormat in ApacheCXF is used however there is a need for getting some information form SOAP headers "" and pass it to Camel. My question is how to do this? When I use Interceptor in Apache CXF I can get information that I need but I cannot pass it then to Camel. The class below is a CXF Interceptor
public class MyInterceptor extends AbstractSoapInterceptor {
//..... some variables
#Override
public void handleMessage(SoapMessage message) throws Fault {
//..some logic and then setting a variable
message.getExchange().put("Foo", "Bar");
}
}
... and class below is Camel Processor that is eventually called:
public class MyCamelProcessor implements Processor {
#Override
public void process(Exchange exchange) throws Exception {
//how can I read information from CXF Intercptor here?
//how can I read "Foo" value?
}
}
I understand that Exchange class that is used by Apache CXF is different then Exchange used by Camel however there should be a way of passing information between these two integrated technologies?
Finally, I solved it how follow:
In my context, I have a consumer service with camel-cxf component which is routed to Processor.
CxfEndpoint class from Camel has a method call setInInterceptors:
public void setInInterceptors(List<org.apache.cxf.interceptor.Interceptor<? extends org.apache.cxf.message.Message>> interceptors)
Therefore, if we define the next in our beans definitions file:
...
<cxf:cxfEndpoint id="consumerId"
address="/myservice"
serviceClass="com.example.service.MyServiceSEI">
<cxf:inInterceptors>
<ref bean="myInterceptor"/>
</cxf:inInterceptors>
</cxf:cxfEndpoint>
<bean id="myInterceptor" class="com.example.interceptors.MyInterceptor" />
Then, in our custom Interceptor we can set any variable in a map
...
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
...
public class MyInterceptor extends AbstractSoapInterceptor {
public MyInterceptor() {
super(Phase.RECEIVE);
}
#Override
public void handleMessage(SoapMessage message) throws Fault {
//..some logic and then setting a variable
message.getExchange().put("Foo", "Bar");
}
}
Finally, we can get the variables in our Processor, using org.apache.cxf.message.Message class, different from org.apache.camel.Message used with Exchange.getIn() method
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.cxf.message.Message;
import org.apache.camel.component.cxf.common.message.CxfConstants;
public class MyCamelProcessor implements Processor {
#Override
public void process(Exchange exchange) throws Exception {
//how can I read information from CXF Intercptor here?
//how can I read "Foo" value?
Message cxfMessage = exchange.getIn().getHeader(CxfConstants.CAMEL_CXF_MESSAGE, Message.class);
String foo = (String) cxfMessage.getExchange().get("Foo");
// read message from camel context
org.apache.camel.Message inMessage = exchange.getIn();
...
}
}
Thanks: http://camel.465427.n5.nabble.com/Getting-entire-Soap-Message-with-header-and-body-in-Payload-mode-td5753162.html
i seem to run into a small issue when using #Autowired into a custom cxf interceptor.
My use case is that i want to log soap messages and send these using AMQP to another system. This process works for normal services etc.
But whatever i do, the needed properties do not get autowired and stay null.
I checked the Spring DI log and the context is scanned and pickedup, so what am i missing?
Is this even possible in CXF interceptors?
#Component
public class LogInInterceptor extends AbstractSoapInterceptor {
private #Value("#{rabbitMQProperties['rabbitmq.binding.log.soap']}")
String binding;
#Autowired
AmqpTemplate amqpTemplate;
public LogInInterceptor() {
super(Phase.RECEIVE);
}
#Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
logIt(soapMessage);
}
private void logIt(SoapMessage message) throws Fault {
// rest of the code omitted...!!!
amqpTemplate.convertAndSend(binding, buffer.toString());
}
}
You can't mix #InInterceptors (a CXF annotation) and #Component (a Spring annotation). That will create two separate instances of your interceptor: the one whose dependencies are getting injected by Spring, and one created by CXF. (You are providing class names in the #InInterceptors annotation, not a bean ID, so CXF has no way of knowing that you already created an instance in the Spring context.)
Remove the #InInterceptors annotation and, in addition to the component scan:
<context:component-scan base-package="org.example.config"/>
You also need something like this in your application context:
<jaxws:endpoint id="myWebService" address="/MyWebService">
<jaxws:inInterceptors>
<ref bean="myInInterceptor" />
</jaxws:inInterceptors>
</jaxws:endpoint>
I know this is an old question, but Jonathan W's answer helped me and I would like to add to it.
This is how I got custom interceptors and #Autowired to work with Spring Boot 1.3.1:
http://cxf.apache.org/docs/jax-ws-configuration.html
import java.util.Arrays;
import javax.jws.WebService;
import org.apache.cxf.Bus;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
#Configuration
#EnableAutoConfiguration
#ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class Application extends SpringBootServletInitializer {
#Autowired
private ApplicationContext applicationContext;
#Autowired
private MyInterceptor myInterceptor;
#Autowired
private HelloWorldImpl helloWorldImpl;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// Replaces the need for web.xml
#Bean
public ServletRegistrationBean servletRegistrationBean(ApplicationContext context) {
return new ServletRegistrationBean(new CXFServlet(), "/api/*");
}
// Replaces cxf-servlet.xml
#Bean
// <jaxws:endpoint id="helloWorld" implementor="demo.spring.service.HelloWorldImpl" address="/HelloWorld"/>
public EndpointImpl helloService() {
Bus bus = (Bus) applicationContext.getBean(Bus.DEFAULT_BUS_ID);
EndpointImpl endpoint = new EndpointImpl(bus, helloWorldImpl);
// Set interceptors here
endpoint.setInInterceptors(Arrays.asList(myInterceptor));
endpoint.publish("/hello");
return endpoint;
}
// Used when deploying to a standalone servlet container, i.e. tomcat
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
// Web service endpoint
#WebService(endpointInterface = "demo.spring.service.HelloWorld")
//#InInterceptors not defined here
public static class HelloWorldImpl {
}
public static class MyInterceptor extends LoggingInInterceptor {
// #Autowired works here
}
}
The problem is clear as I mentioned in the title, any help would be appreciated...
By the way, my services are running on Jboss 4.2.2GA and I am using MyEclipse7.5
Moreover, here what I have tried before but did not work for me;
#Stateless
#WebService(name = "BaseService", targetNamespace = "http://base.ws.listingapi.gg.com")
#SOAPBinding(style = SOAPBinding.Style.RPC)
#WebContext(contextRoot = "/listingapi/ws")
public abstract class BaseService {
..
MessageContext mctx = webServiceContext.getMessageContext();
webServiceContext.getUserPrincipal(); //WITH THIS ONE I could get the username but of course not password..
System.out.println(mctx.get("password"));
Map http_headers = (Map) mctx.get(MessageContext.HTTP_REQUEST_HEADERS);
List userList = (List) http_headers.get("Username");
List passList = (List) http_headers.get("Password");
[SOLVED]
I have found the solution, here it is;
#Context
protected HttpServletRequest request;
Or
#Context
protected WebServiceContext context;
...
request.getUserPrincipal().getName();
//OR
context.getUserPrincipal().getName();
//will return the username used to getting logged in
[SOLVED] I have found the solution, here it is;
#Context
protected HttpServletRequest request;
Or
#Context
protected WebServiceContext context;
...
request.getUserPrincipal().getName();
//OR
context.getUserPrincipal().getName();
//will return the username used to getting logged in
I cannot figure out how to retrieve the session ID from a given JAX-RS webservice request. I assume it is available, but I do not know how to retrieve it.
I am NOT using CXF. I would be grateful for any assistance.
You can use the #Context annotation to get the current instance of the HttpServletRequest.
#Path("/session-id.txt")
public class SessionIdResource {
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getSessionId(#Context HttpServletRequest request) {
return request.getSession(true).getId();
}
}