Page Edited :
CXF20DOC :
Servlet Transport
Servlet Transport has been edited by willem jiang (Apr 20, 2008). Change summary: Added some descriptions about how to setup the CXFNonSpringServlet Setting up your web.xmlTo set up CXF to use a Servlet you'll need to add the CXFServlet to your web.xml: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> </web-app> To create services that use this transport you can either use the CXF APIs (for instance, JAX-WS) or you can create an XML file which registers services for you. Publishing an endpoint with XMLNOTE: this requires a snapshot from Feb 12 2007 or later. CXF uses Spring to provide XML configuration of services. This means that first we'll want to load Spring via a Servlet listener and tell it where oure XML configuration file is: <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:com/acme/ws/services.xml </param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> NOTE: this is in the process of being simplified so will not have to add the ContextLoaderListener in future releases. The next step is to actually write the configuration file: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <jaxws:endpoint id="greeter" implementor="org.apache.hello_world_soap_http.GreeterImpl" address="/Greeter1"/> </beans> Here we're creating a JAX-WS endpoint based on our implementation class, GreeterImpl. NOTE: We're publishing this class at the address "http://localhost/mycontext/services/Greeter1", but we set the jaxws:[EMAIL PROTECTED] with a related path "/Greeter1". Since Servlets are not aware of their HTTP address, the Servlet will listen for requests on all available hosts/ports that it has been set up to listen on by its container. Publishing an endpoint with the APIOnce your Servlet is registered in your web.xml, you should set the default bus with CXFServlet's bus to make sure that CXF uses it as it's HTTP Transport. Simply publish with the related path "Greeter" and your service should appear at the address you specify: // cxf is the instance of the CXFServlet, you could also get this instance by extending the CXFServlet Bus bus = cxf.getBus(); BusFactory.setDefaultBus(bus); Endpoint.publish("/Greeter", new GreeterImpl()); The one thing you must ensure is that your CXFServlet is set up to listen on that path. Otherwise the CXFServlet will never receive the requests. Using the servlet transport without SpringSome user who don't want to touch any Spring stuff could also publish the endpoint with CXF servlet transport. First you should extends the CXFNonSpringServlet and override the method loadBus which below codes: @Override public void loadBus(ServletConfig servletConfig) throws ServletException { super.loadBus(servletConfig); // You could add the endpoint publish codes here Bus bus = cxf.getBus(); BusFactory.setDefaultBus(bus); Endpoint.publish("/Greeter", new GreeterImpl()); } If you are using the Jetty as the embedded servlet engine, you could publish endpoint like this: // Setup the system properties to use the CXFBusFactory not the SpringBusFactory String busFactory = System.getProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME); System.setProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME, "org.apache.cxf.bus.CXFBusFactory"); try { // Start up the jetty embedded server httpServer = new Server(9000); ContextHandlerCollection contexts = new ContextHandlerCollection(); httpServer.setHandler(contexts); Context root = new Context(contexts, "/", Context.SESSIONS); CXFNonSpringServlet cxf = new CXFNonSpringServlet(); ServletHolder servlet = new ServletHolder(cxf); servlet.setName("soap"); servlet.setForcedPath("soap"); root.addServlet(servlet, "/soap/*"); httpServer.start(); Bus bus = cxf.getBus(); setBus(bus); BusFactory.setDefaultBus(bus); GreeterImpl impl = new GreeterImpl(); Endpoint.publish("/Greeter", impl); } catch (Exception e) { throw new RuntimeException(e); } finally { // clean up the system properties if (busFactory != null) { System.setProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME, busFactory); } else { System.clearProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME); } } Accessing the MessageContext and/or HTTP Request and ResponseSometimes you'll want to access more specific message details in your service implementation. One example might be accessing the actual request or response object itself. This can be done using the WebServiceContext object. First, declare a private field for the WebServiceContext in your service implementation, and annotate it as a resource: @Resource
private WebServiceContext context;
Then, within your implementing methods, you can access the MessageContext, HttpServletRequest, and HttpServletResponse as follows: MessageContext ctx = context.getMessageContext(); HttpServletRequest request = (HttpServletRequest) ctx.get(AbstractHTTPDestination.HTTP_REQUEST); HttpServletRequest response = (HttpServletResponse) ctx.get(AbstractHTTPDestination.HTTP_RESPONSE); Of course, it is always a good idea to program defensively if using transport-specific entities like the HttpServletRequest and HttpServletResponse. If the transport were changed (for instance to the JMS transport), then these values would likely be null. |
Unsubscribe or edit your notifications preferences