Filter

com.sun.net.httpserver.Filter Example

In this example we shall show you how to make use of Filter class, A Filter is mainly used for pre or post processing of the incoming requests such as:

  • Examine or modify the request headers.
  • Set attribute Objects in the exchange using setAttribute(String name, Object value), which other filters or the exchange handler can access.
  • Invoke the next filter in the chain, by calling doFilter(HttpExchange exchange, Filter.Chain chain) where all subsequent filters in the Chain will be called.
  • Terminate the chain of invocation, by not calling doFilter(HttpExchange exchange, Filter.Chain chain). However, this Filter must use the HttpExchange to send back an appropriate response.

These are the steps taken for processing HTTP request using filters:

  1. Pre-processing occurs before the application’s HttpHandler is invoked, and post-processing occurs after the HttpHandler returns.
  2. Filters are organised in chains, and are associated with HttpContext instances.
  3. Each Filter in the chain, invokes the next Filter within its own doFilter(HttpExchange exchange, Filter.Chain chain) implementation. The final Filter in the chain invokes the applications HttpHandler.

In our previous example, we explained the HttpServer class which implements a simple HTTP server where we have an HttpHandler which process all the incoming request. However, in this example, we will let our Filter to pre process all the incoming request then passing them to the HttpHandler to just building and rendering the response.

1. Example

SimpleHttpServer class has a constructor which takes four given parameters (int port, String context, Filter filter, HttpHandler handler) and returns a new SimpleHttpServer. Also, it contains start() which allows to start the newly created HttpServer.

SimpleHttpServer.java:

package com.jcg;

import java.io.IOException;
import java.net.InetSocketAddress;

import com.sun.net.httpserver.Filter;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

/**
 * @author ashraf
 * 
 */
@SuppressWarnings("restriction")
public class SimpleHttpServer {

	private HttpServer httpServer;

	/**
	 * Instantiates a new simple http server.
	 *
	 * @param port the port
	 * @param context the context
	 * @param handler the handler
	 */
	public SimpleHttpServer(int port, String context, Filter filter, HttpHandler handler) {
		try {
			
			// Create HttpServer which is listening on the given port 
			httpServer = HttpServer.create(new InetSocketAddress(port), 0);
			
			// Create a new context for the given context and handler
			HttpContext httpContext = httpServer.createContext(context, handler);
			
			// Add HttpRequestFilter to the context
			httpContext.getFilters().add(filter);
			
			// Create a default executor
			httpServer.setExecutor(null);
			
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Start.
	 */
	public void start() {
		this.httpServer.start();
	}

}

HttpRequestFilter class contains the logic to pre process all the incoming requests, it takes the request URI query parameters (fName, lName), builds a string like “Ashraf Sarhan” and set it as request attribute paramString. Finally, it chain the request to the HttpRequestHandler class.

HttpRequestFilter.java:

package com.jcg;

import java.io.IOException;
import java.net.URI;

import com.sun.net.httpserver.Filter;
import com.sun.net.httpserver.HttpExchange;

/**
 * @author ashraf_sarhan
 * 
 */
@SuppressWarnings("restriction")
public class HttpRequestFilter extends Filter {

	private static final String FILTER_DESC = "HttpRequestFilter creates a String from the request parameters and pass it to HttpRequestHandler";

	private static final String F_NAME = "fname";
	private static final String L_NAME = "lname";

	private static final int PARAM_NAME_IDX = 0;
	private static final int PARAM_VALUE_IDX = 1;

	private static final String AND_DELIMITER = "&";
	private static final String EQUAL_DELIMITER = "=";

	@Override
	public String description() {
		return FILTER_DESC;
	}

	@Override
	public void doFilter(HttpExchange exchange, Chain chain) throws IOException {
		
		// Create a string form the request query parameters
		URI uri = exchange.getRequestURI();
		String paramString = createStringFromQueryParams(uri);
		
		// Set paramString as a request attribute
		exchange.setAttribute("paramString", paramString);
		
		// Chain the request to HttpRequestHandler
		chain.doFilter(exchange);

	}

	private String createStringFromQueryParams(URI uri) {

		String fName = "";
		String lName = "";
		// Get the request query
		String query = uri.getQuery();
		if (query != null) {
			System.out.println("Query: " + query);
			String[] queryParams = query.split(AND_DELIMITER);
			if (queryParams.length > 0) {
				for (String qParam : queryParams) {
					String[] param = qParam.split(EQUAL_DELIMITER);
					if (param.length > 0) {
						for (int i = 0; i < param.length; i++) {
							if (F_NAME.equalsIgnoreCase(param[PARAM_NAME_IDX])) {
								fName = param[PARAM_VALUE_IDX];
							}
							if (L_NAME.equalsIgnoreCase(param[PARAM_NAME_IDX])) {
								lName = param[PARAM_VALUE_IDX];
							}
						}
					}
				}
			}
		}

		return "Hello, " + fName + " " + lName;
	}

}

HttpRequestHandler class contains the logic for just building, rendering the response by getting the request attribute paramString value and returns it back to the user like “Hello, Ashraf Sarhan”.

HttpRequestHandler.java:

package com.jcg;

import java.io.IOException;
import java.io.OutputStream;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

/**
 * @author ashraf
 * 
 */
@SuppressWarnings("restriction")
public class HttpRequestHandler implements HttpHandler {

	private static final String PARAM_STRING = "paramString";

	private static final int HTTP_OK_STATUS = 200;

	public void handle(HttpExchange exchange) throws IOException {

		// Get the paramString form the request
		String response = exchange.getAttribute(PARAM_STRING).toString();
		System.out.println("Response: " + response);

		// Set the response header status and length
		exchange.sendResponseHeaders(HTTP_OK_STATUS, response.getBytes().length);

		// Write the response string
		OutputStream os = exchange.getResponseBody();
		os.write(response.getBytes());
		os.close();
	}

}

HttpServerTest creates a new HttpServer then it calls the start() method to start the HttpServer. Now, we can go to our browser, hit this url http://localhost:8000/app?fName=Ashraf&lName=Sarhan and see the response.

HttpServerTest.java:

package com.jcg;

/**
 * @author ashraf
 * 
 */
public class HttpServerTest {

	private static final String CONTEXT = "/app";
	private static final int PORT = 8000;

	public static void main(String[] args) throws Exception {

		// Create a new SimpleHttpServer with HttpRequestFilter and HttpRequestHandler
		SimpleHttpServer simpleHttpServer = new SimpleHttpServer(PORT, CONTEXT,
				new HttpRequestFilter(), new HttpRequestHandler());

		// Start the server
		simpleHttpServer.start();
		System.out.println("Server is started and listening on port " + PORT);
	}

}

Output:

  1. Console:
    Server is started and listening on port 8000
    Query: fName=Ashraf&lName=Sarhan
    Response: Hello, Ashraf Sarhan
    
  2. Browser:
    Figure1: Http Filter Demo
    Figure1: Http Filter Demo

Download the Source Code of this example

This was an example of of how to use Filter class.

Download
You can download the full source code of this example here: HttpServerFilterExampleCode.zip

Ashraf Sarhan

Ashraf Sarhan is a passionate software engineer, an open source enthusiast, has a Bsc. degree in Computer and Information Systems from Alexandria University. He is experienced in building large, scalable and distributed enterprise applications/service in multiple domains. He also has a keen interest in JavaEE, SOA, Agile and Big Data technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button