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 theHttpExchange
to send back an appropriate response.
These are the steps taken for processing HTTP request using filters:
- Pre-processing occurs before the application’s
HttpHandler
is invoked, and post-processing occurs after theHttpHandler
returns. - Filters are organised in chains, and are associated with
HttpContext
instances. - Each
Filter
in the chain, invokes the nextFilter
within its owndoFilter(HttpExchange exchange, Filter.Chain chain)
implementation. The finalFilter
in the chain invokes the applicationsHttpHandler
.
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:
- Console:
Server is started and listening on port 8000 Query: fName=Ashraf&lName=Sarhan Response: Hello, Ashraf Sarhan
- Browser:
Download the Source Code of this example
This was an example of of how to use Filter
class.
You can download the full source code of this example here: HttpServerFilterExampleCode.zip