HowToDoInJava

  • Python
  • Java
  • Spring Boot
  • Dark Mode
Home / Jersey / Jersey Logging Request and Response Entities using Filter

Jersey Logging Request and Response Entities using Filter

By default, Jersey uses JUL for logging – and does not print request/response entity bodies in logs. To print entity content, you must create your own LoggingFiler, and register it in place of default org.glassfish.jersey.filter.LoggingFilter. In this example, I am creating one such basic CustomLoggingFilter which extends org.glassfish.jersey.filter.LoggingFilter and implements ContainerRequestFilter and ContainerResponseFilter interfaces so that it can intercept the ongoing requests and responses.

Table of Contents

Create CustomLoggingFilter
Register CustomLoggingFilter
Log statements with default LoggingFilter 
Log statements with CustomLoggingFilter

Create CustomLoggingFilter

Let’s go straight to custom logging filter class for this jersey demo.

package com.howtodoinjava.jersey.provider;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;

import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.message.internal.ReaderWriter;

public class CustomLoggingFilter extends LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter 
{
	@Override
	public void filter(ContainerRequestContext requestContext)	throws IOException 
	{
		StringBuilder sb = new StringBuilder();
		sb.append("User: ").append(requestContext.getSecurityContext().getUserPrincipal() == null ? "unknown"
						: requestContext.getSecurityContext().getUserPrincipal());
		sb.append(" - Path: ").append(requestContext.getUriInfo().getPath());
		sb.append(" - Header: ").append(requestContext.getHeaders());
		sb.append(" - Entity: ").append(getEntityBody(requestContext));
		System.out.println("HTTP REQUEST : " + sb.toString());
	}

	private String getEntityBody(ContainerRequestContext requestContext) 
	{
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		InputStream in = requestContext.getEntityStream();
		
		final StringBuilder b = new StringBuilder();
		try 
		{
			ReaderWriter.writeTo(in, out);

			byte[] requestEntity = out.toByteArray();
			if (requestEntity.length == 0)
			{
				b.append("").append("\n");
			}
			else
			{
				b.append(new String(requestEntity)).append("\n");
			}
			requestContext.setEntityStream( new ByteArrayInputStream(requestEntity) );

		} catch (IOException ex) {
			//Handle logging error
		}
		return b.toString();
	}

	@Override
	public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException 
	{
		StringBuilder sb = new StringBuilder();
		sb.append("Header: ").append(responseContext.getHeaders());
		sb.append(" - Entity: ").append(responseContext.getEntity());
		System.out.println("HTTP RESPONSE : " + sb.toString());
	}
}

Register CustomLoggingFilter

To register this CustomLoggingFilter, register in this way.

package com.howtodoinjava.jersey;

import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;

import com.howtodoinjava.jersey.provider.CustomLoggingFilter;

public class CustomApplication extends ResourceConfig 
{
	public CustomApplication() 
	{
		packages("com.howtodoinjava.jersey");
		register(JacksonFeature.class);

		register(CustomLoggingFilter.class);
	}
}

Log statements with default LoggingFilter

Now if you try to use any existing REST API without CustomLoggingFilter, logs will appear in this way.

Request

Jersey-custom-logging

Logs

Sep 30, 2015 6:18:41 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Server has received a request on thread http-bio-8080-exec-4
1 > POST http://localhost:8080/JerseyDemos/rest/employees
1 > accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
1 > accept-encoding: gzip, deflate
1 > accept-language: null
1 > cache-control: no-cache
1 > connection: keep-alive
1 > content-length: 35
1 > content-type: application/json; charset=UTF-8
1 > host: localhost:8080
1 > pragma: no-cache
1 > user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0

Sep 30, 2015 6:18:41 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Server responded with a response on thread http-bio-8080-exec-4
1 < 200
1 < Content-Type: application/json

Log statements with CustomLoggingFilter

After adding CustomLoggingFilter, you will get much better logs like below.

HTTP REQUEST : User: unknown - Path: employees - Header: {host=[localhost:8080], user-agent=[Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0], accept=, accept-language=[null], accept-encoding=[gzip, deflate], content-type=[application/json; charset=UTF-8], content-length=[35], connection=[keep-alive], pragma=[no-cache], cache-control=[no-cache]} - Entity: {"id":2,"name":"Alex Kolenchiskey"}

HTTP RESPONSE : Header: {Content-Type=[application/json]} - Entity: Employee [id=2, name=Alex Kolenchiskey]
Please feel free to add/remove information from log statements as per your need. There is plenty of other useful information you may add in these logs.

Happy Learning !!

Was this post helpful?

Let us know if you liked the post. That’s the only way we can improve.

Share this:

  • Twitter
  • Facebook
  • LinkedIn
  • Reddit

About Lokesh Gupta

A family guy with fun loving nature. Love computers, programming and solving everyday problems. Find me on Facebook and Twitter.

Feedback, Discussion and Comments

  1. Ahmed

    November 10, 2016

    Thanks, This is very helpful.

    responseContext.getEntity() returnsobject not html, any idea how to solve this.

    • Joe

      February 21, 2019

       InputStream inputStream = response.readEntity(InputStream.class); // use raw InputStream to ignore Content-Type when parsing
      
      String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
      
  2. Deborpita

    May 9, 2016

    the log file, where it would be generated??

    • sandy2431

      May 16, 2016

      Nowhere. Only in Cloud. Call It Magic.

  3. Andrew

    December 17, 2015

    The same error with Jersey 2.21.

    • Lokesh Gupta

      December 17, 2015

      When I wrote the example, 2.19 was latest available Jersey version.

      &lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd;
      	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
      	&lt;groupId&gt;com.howtodoinjava.jersey&lt;/groupId&gt;
      	&lt;artifactId&gt;JerseyDemos&lt;/artifactId&gt;
      	&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
      	&lt;packaging&gt;war&lt;/packaging&gt;
      	&lt;repositories&gt;
      		&lt;repository&gt;
      			&lt;id&gt;maven2-repository.java.net&lt;/id&gt;
      			&lt;name&gt;Java.net Repository for Maven&lt;/name&gt;
      			&lt;url&gt;http://download.java.net/maven/2/&lt;/url&gt;
      			&lt;layout&gt;default&lt;/layout&gt;
      		&lt;/repository&gt;
      	&lt;/repositories&gt;
      	&lt;properties&gt;
      		&lt;jersey2.version&gt;2.19&lt;/jersey2.version&gt;
      		&lt;jaxrs.version&gt;2.0.1&lt;/jaxrs.version&gt;
      	&lt;/properties&gt;
      	&lt;dependencies&gt;
      		&lt;!-- JAX-RS --&gt;
      		&lt;dependency&gt;
      			&lt;groupId&gt;javax.ws.rs&lt;/groupId&gt;
      			&lt;artifactId&gt;javax.ws.rs-api&lt;/artifactId&gt;
      			&lt;version&gt;${jaxrs.version}&lt;/version&gt;
      		&lt;/dependency&gt;
      		&lt;!-- Jersey 2.19 --&gt;
      		&lt;dependency&gt;
      			&lt;groupId&gt;org.glassfish.jersey.containers&lt;/groupId&gt;
      			&lt;artifactId&gt;jersey-container-servlet&lt;/artifactId&gt;
      			&lt;version&gt;${jersey2.version}&lt;/version&gt;
      		&lt;/dependency&gt;
      		&lt;dependency&gt;
      			&lt;groupId&gt;org.glassfish.jersey.core&lt;/groupId&gt;
      			&lt;artifactId&gt;jersey-server&lt;/artifactId&gt;
      			&lt;version&gt;${jersey2.version}&lt;/version&gt;
      		&lt;/dependency&gt;
      		&lt;dependency&gt;
      			&lt;groupId&gt;org.glassfish.jersey.core&lt;/groupId&gt;
      			&lt;artifactId&gt;jersey-client&lt;/artifactId&gt;
      			&lt;version&gt;${jersey2.version}&lt;/version&gt;
      		&lt;/dependency&gt;
      		&lt;dependency&gt;
      			&lt;groupId&gt;org.glassfish.jersey.media&lt;/groupId&gt;
      			&lt;artifactId&gt;jersey-media-json-jackson&lt;/artifactId&gt;
      			&lt;version&gt;${jersey2.version}&lt;/version&gt;
      		&lt;/dependency&gt;
      	&lt;/dependencies&gt;
      	&lt;build&gt;
      		&lt;finalName&gt;JerseyDemos&lt;/finalName&gt;
      		&lt;plugins&gt;
      			&lt;plugin&gt;
      				&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
      				&lt;configuration&gt;
      					&lt;source&gt;1.7&lt;/source&gt;
      					&lt;target&gt;1.7&lt;/target&gt;
      				&lt;/configuration&gt;
      			&lt;/plugin&gt;
      		&lt;/plugins&gt;
      	&lt;/build&gt;
      &lt;/project&gt;
      
  4. velmurugan

    September 30, 2015

    what version of jersey are you using for this example?.
    LoggerFilter is a final class, So we can not extend this filter for custom logging.. I am using the jersey version 2.21.

Comments are closed on this article!

Search Tutorials

Jersey Tutorial

  • Jersey – Hello World
  • Jersey2 – Hello World
  • Jersey – quickstart-archetype
  • Jersey – Custom Logging
  • Jersey – Set Cookie
  • Jersey – File Download
  • Jersey – File Upload
  • Jersey – Multi-File Upload
  • Jersey – Exception Handling
  • Jersey – MOXy JSON
  • Jersey – JSONP
  • Jersey – Google Gson
  • Jersey – Security

Jersey Client

  • Jersey Client – Access REST APIs
  • Jersey Client – Authentication
  • Jersey Client – Set Cookie

Meta Links

  • About Me
  • Contact Us
  • Privacy policy
  • Advertise
  • Guest and Sponsored Posts

Recommended Reading

  • 10 Life Lessons
  • Secure Hash Algorithms
  • How Web Servers work?
  • How Java I/O Works Internally?
  • Best Way to Learn Java
  • Java Best Practices Guide
  • Microservices Tutorial
  • REST API Tutorial
  • How to Start New Blog

Copyright © 2020 · HowToDoInjava.com · All Rights Reserved. | Sitemap

  • Java 15 New Features
  • Sealed Classes and Interfaces
  • EdDSA (Ed25519 / Ed448)