Sep 2, 2011 ... Learn to perform web service message logging using Apache ... Apache CXF is a
web service framework used to develop, build and deploy ...
Web service message logging with Apache CXF Learn to perform web service message logging using Apache CXF Skill Level: Intermediate Rajeev J. Hathi (
[email protected]) Java Architect, Writer
02 Sep 2011 Logging can be used as a tool to monitor and debug the application. In this article, you will learn how to perform Web service message logging with Apache CXF. The article will demonstrate various ways in which you can implement message logging. It will illustrate the use of significant CXF features like Interceptors and Features to perform message logging. The article will also demonstrate message logging using Spring based bean configuration.
Overview Apache CXF is a web service framework used to develop, build and deploy web services. CXF supports many features that can be used by the developers to develop and deploy Web service based application. One such feature is logging. Logging here effective means logging Web service messages. CXF makes use of standard Java logging API to log the messages. It allows you to log both incoming and outgoing messages. The messages can be logged both at the client and the server side. Logging is important as one can see the actual SOAP payload being passed to the server and back. It can be useful as a debugging tool. Logging can be implemented in CXF through the concept of Interceptors and Features. The article will demonstrate a simple Web service message logging using the said concepts. You will also look at using Spring based bean configuration to configure the message logging. You will develop a simple Web service using JAX-WS frontend or API of CXF. Let's
Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 1 of 9
developerWorks®
ibm.com/developerWorks
consider an online Learning Management System (LMS) where typical functionalities would include user management, course creation, discussion forum, gradebook maintanence, content management etc. As part of this article, we will take the 'Course Creation' use case and develop a simple Web service class called CourseBuilder. The article indirectly will show how one can develop a simple Web service and publish it as a JAX-WS endpoint. The primary objective though will be to show the logging mechanisms. The article focuses only on server side logging. You can easily emulate client side logging once you understand the server side logging. Our Web service class will look like the following CourseBuilderImpl Web service class @WebService public class CourseBuilderImpl implements CourseBuilder { public String createCourse(Course course) { System.out.println("Course code is " + course.getCode()); System.out.println("Course title is " + course.getTitle()); return "Course created successfully"; } }
The above Web service class CourseBuilderImpl is pretty simple. The createCourse method takes a Course bean as a paramater and returns the status string indicating successful creation of course. You will now log the service messages on the console. The service messages effectively means the SOAP payload or the actual data that takes the form of method parameters and return types. You will display this payload on the console by turning on the logging feature.
Logging using Interceptors Interceptors in CXF are components that intercepts SOAP messages. It can intercept incoming messages as well as outgoing messages. And therefore one can configure these interceptors either at the client application or on the server side or both. CXF provides number of built-in interceptors. Two such interceptors perform logging of messages and they are LoggingInInterceptor and LoggingOutInterceptor interceptors. You will use these interceptors to perform server side logging. The below code shows the way: Server code public final class Server { public static void main(String args[]) throws Exception { CourseBuilderImpl implementor = new CourseBuilderImpl();
Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 2 of 9
ibm.com/developerWorks
developerWorks®
JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean(); svrFactory.setAddress("http://localhost:9000/CourseBuilder"); svrFactory.setServiceBean(implementor); svrFactory.getInInterceptors().add(new LoggingInInterceptor()); svrFactory.getOutInterceptors().add(new LoggingOutInterceptor()); svrFactory.create(); } }
The above code uses JaxWsServerFactoryBean server factory class to publish CourseBuilder service as JAX-WS endpoint. As you can see it sets the implementation class and the endpoint address. The create method starts the embedded standalone Jetty server. The significant part of the code is highlighted in the bold. It uses the two interceptors viz. LoggingInInterceptor and LoggingOutInterceptor. These are added to the factory class before the call to create method is made. This highlighted code enables the logging feature on the server side for both incoming and outgoing message. Once you run the client application, it will log the following output on the server console: Server console
The above server console output shows the inbound and outbound SOAP payload. You can also control the size of the logging content by specifying it in the constructor. The size indicates number of bytes. For example, new LoggingInInterceptor(1024). So as you see logging interceptors makes it so easy to log your service messages. You can also make use of annotations to implement logging. The following code makes use of annotations to implement logging through interceptors. Logging using interceptor annotations @WebService @InInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingInInterceptor")
Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 3 of 9
developerWorks®
ibm.com/developerWorks
@OutInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingOutInterceptor") public class CourseBuilderImpl implements CourseBuilder { ...
The @InInterceptors and @OutInterceptors annotations can be used to define inbound and outbound interceptors respectively. The annotations can be declared in the service class or service endpoint interface (SEI). If the said annotations are placed in the SEI then the logging is enabled both on the client and server application. In the above code, the annotation is declared in the CourseBuilderImpl service implementation class and therefore the messages will be logged only on the server side.
Logging using Features Features in CXF works more like decorators. It is applied to client, server and bus components. It basically extends the functionality of the client, server or the bus. CXF provides some of the built-in Feature implementations and one of them is LoggingFeature feature class. The LoggingFeature class performs logging of SOAP messages. We will revist the server code shown earlier. You will now use LoggingFeature feature class instead of interceptors: Logging feature public final class Server { public static void main(String args[]) throws Exception { CourseBuilderImpl implementor = new CourseBuilderImpl(); JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean(); svrFactory.setAddress("http://localhost:9000/CourseBuilder"); svrFactory.setServiceBean(implementor); svrFactory.getFeatures().add(new LoggingFeature()); svrFactory.create(); } }
What is CXF Bus? A CXF bus can be thought of as a global or application level component that manages the core or infrastructure components (also called as extensions) of the framework and also acts as a interceptor provider. If you implement logging at the bus level, then the said logging feature will be common to all the service endpoints configured in the server or client runtime.
The highlighted code says it all. It will log both inbound and outbound messages i.e. messages received by the server and the response returned by the server. The LoggingFeature feature class in turn uses logging interceptors. Direct use of interceptors though can give you better control. For example, if you only want to log Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 4 of 9
ibm.com/developerWorks
developerWorks®
only incoming message and not the outgoing, in that case one can use only LoggingInInterceptor interceptor class and need not use LoggingFeature class. Just as with logging interceptors, LoggingFeature class allows you to set the limit size for logging content in number of bytes. The limit size can be specified in the constructor like below: Logging feature with size limit public final class Server { public static void main(String args[]) throws Exception { JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean(); ... // This will only log upto 1K or 1024 characters svrFactory.getFeatures().add(new LoggingFeature(1024)); ... } }
LoggingFeature feature class also allows you to set the output destination of the messages to be logged. One can configure to log the message to stdout (Console), stderr (Error console) or to a file. You can set the output destination for both incoming and outgoing messages. The below code shows the use of output destination with LoggingFeature class. Logging feature with output destination public final class Server { public static void main(String args[]) throws Exception { JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean(); ... svrFactory.getFeatures().add( new LoggingFeature("", "file://home/myLog.txt")); ... } }
A different LoggingFeature constructor above takes two String parameters. These parameters indicate the output log destination for the incoming and outgoing messages respectively. From the above code, the inbound message will be logged to the console and the outbound message will be logged to the file. With Features, you can also use annotations. The @Features annotation is used to specify features. The below code illustrates the use of @Features annotation. Logging feature using annotation @WebService
Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 5 of 9
developerWorks®
ibm.com/developerWorks
@Features(features = "org.apache.cxf.feature.LoggingFeature") public class CourseBuilderImpl implements CourseBuilder { ...
In the above code, the @Features annotation is used to specify the LoggingFeature feature class to perform logging on the server side. If you do not wish to use interceptor or feature annotation then you can simply use @Logging annotation to log the messages. The following code makes the logging even simpler: @Logging annotation @WebService @Logging public class CourseBuilderImpl implements CourseBuilder { ...
Logging using Spring based bean configuration With CXF, you can also publish your Web service using Spring based bean configuration file. The obvious advantage of using the Spring configuration file is you can dynamically add features and interceptors to your service bean without the need of re-compiling your code. Readers are encouraged to read one of my earlier article on Web service development with Apache CXF and Spring. It walks you through developing and eventually publishing Web service using Spring configuration file. The below code shows the configuration file that defines CourseBuilderImpl bean as JAX-WS endpoint. Configuring CourseBuilderImpl service bean as JAX-WS endpoint
Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 6 of 9
ibm.com/developerWorks
developerWorks®
The element is used to define the CourseBuilderImpl service bean as a JAX-WS endpoint. The endpoint URL is relative to the web context (This is ofcourse if you are using CXFServlet as a http transport). Now to use the logging interceptors, you need to change the above code to look like the following: Configuring logging interceptors ...
The above revised code now has two interceptor beans added viz. LoggingInInterceptor and LoggingOutInterceptor. The reference of these beans is passed to the CourseBuilderImpl service bean through the use of and elements respectively. This will ensure that both inbound and outbound service messages are logged. Similarly, you can also configure logging feature through Spring. The below code illustrates logging feature. Configuring logging feature ...
As you can see from the above code, element is used to Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 7 of 9
developerWorks®
ibm.com/developerWorks
specify the logging feature. To summarize, we explored the CXF native features like Interceptors and Features to perform service message logging. You can achieve the message logging programmatically, through annotations and using Spring based bean configuration. Apache CXF framework also allows you to integrate logging frameworks like Log4j and SLF4J. It also provides support for various debugging tools for you Web service runtime. For more details on the logging and debugging with CXF, you can visit the following link: CXF Debugging and Logging
Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 8 of 9
ibm.com/developerWorks
developerWorks®
Resources • Web service development with Apache CXF and Aegis Learn to develop a web service using CXF and Aegis databinding • Design and implement POJO Web services using Spring and Apache CXF, Part 1: Introduction to Web services creation using CXF and Spring. • Design and implement POJO Web services using Spring and Apache CXF, Part 2: Create a RESTful Web service • Stay current with developerWorks technical events and webcasts focused on a variety of IBM products and IT industry topics.
About the author Rajeev J. Hathi Rajeev Hathi works as a Software Consultant for the J2EE platform. His professional interests are architecting, designing and developing J2EE-based applications. He has attained SUN certifications in Java and J2EE technologies (Core Java, Web, EJB, Architect). He has contributed several technical papers for IBM developerWorks portal. He is also the co-author of the book Apache CXF Web Service Development. His pastime hobbies are listening to music and watching sports. The author's official web site is http://www.rajeevhathi.com which is a technical blog site and he can be reached at
[email protected].
Web service message logging with Apache CXF © Copyright IBM Corporation 2011. All rights reserved.
Trademarks Page 9 of 9