{"id":1932,"date":"2025-11-24T10:00:03","date_gmt":"2025-11-24T15:00:03","guid":{"rendered":"http:\/\/www.mymiller.name\/wordpress\/?p=1932"},"modified":"2025-11-24T10:00:03","modified_gmt":"2025-11-24T15:00:03","slug":"http-server-filters-jar","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/java_http\/http-server-filters-jar\/","title":{"rendered":"HTTP Server Filters in a Jar"},"content":{"rendered":"\n<p>We discussed the HTTP Server ContextHandler in a Jar&nbsp;one of the methods was ContextHandlerInterface.getFilters() this method returns a list of Filters to apply to incoming HTTP Requests. &nbsp;We subclass&nbsp;com.sun.net.httpserver.Filter for these classes. These can be used to do processing on the request and add attributes to the HTTP Exchange. Filters can block a particular call if needed, or parse data from the call, to set an attribute for you. &nbsp;This example below is a very common example you can find by searching the Internet for Http Filters.<\/p>\n\n\n\n<p>This example searches the HTTP Exchange for Get and Post parameters, to add to a Map&lt;String,Object&gt; that is adds as an attribute to the HttpExchange. &nbsp;Making it a convient way for your ContextHandlerInterface to process the request as parameters are easily accessible.&nbsp;&nbsp;Filters give you a lot of functionality for a simple piece of code.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package name.mymiller.httpserver.filters;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.UnsupportedEncodingException;\nimport java.net.URI;\nimport java.net.URLDecoder;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport com.sun.net.httpserver.Filter;\nimport com.sun.net.httpserver.HttpExchange;\n\nimport name.mymiller.extensions.lang.AdvancedString;\nimport name.mymiller.httpserver.HttpConstants;\n\n\/**\n * @author jmiller Parses the requested URI for parameters and places them into\n *         a map\n *\/\n@SuppressWarnings(\"restriction\")\npublic class ParameterFilter extends Filter\n{\n\n\t\/**\n\t * Retrieve the Parameters Attribute from the Exchange\n\t *\n\t * @param exchange\n\t *            HTTPExchange containing the Parameters Attribute\n\t * @return Map&lt;String, Object> containing the parameters\n\t *\/\n\t@SuppressWarnings(\"unchecked\")\n\tpublic static Map&lt;String, Object> getParametersFromExchange(final HttpExchange exchange)\n\t{\n\t\treturn ((Map&lt;String, Object>) exchange.getAttribute(\"parameters\"));\n\t}\n\n\t\/**\n\t * Method to add a parameter to the HttpExchange.\n\t *\n\t * @param exchange\n\t *            HttpExchange to add the parameter to.\n\t * @param key\n\t *            Key for the parameter\n\t * @param value\n\t *            Value of the parameter\n\t *\/\n\tprivate void addParameter(final HttpExchange exchange, final String key, final String value)\n\t{\n\t\tfinal Map&lt;String, Object> parameters = ParameterFilter.getParametersFromExchange(exchange);\n\n\t\tfinal AdvancedString advKey = new AdvancedString(key);\n\t\tfinal AdvancedString advValue = new AdvancedString(value);\n\n\t\tif (!advKey.containsHtml() &amp;&amp; !advValue.containsHtml())\n\t\t{\n\t\t\tif (parameters.containsKey(key))\n\t\t\t{\n\t\t\t\tfinal Object obj = parameters.get(key);\n\t\t\t\tif (obj instanceof List&lt;?>)\n\t\t\t\t{\n\t\t\t\t\tif (obj instanceof List)\n\t\t\t\t\t{\n\t\t\t\t\t\t@SuppressWarnings(\"unchecked\")\n\t\t\t\t\t\tfinal List&lt;String> values = (List&lt;String>) obj;\n\t\t\t\t\t\tvalues.add(value);\n\t\t\t\t\t}\n\t\t\t\t} else if (obj instanceof String)\n\t\t\t\t{\n\t\t\t\t\tfinal List&lt;String> values = new ArrayList&lt;>();\n\t\t\t\t\tvalues.add((String) obj);\n\t\t\t\t\tvalues.add(value);\n\t\t\t\t\tparameters.put(key, values);\n\t\t\t\t}\n\t\t\t} else\n\t\t\t{\n\t\t\t\tparameters.put(key, advValue);\n\t\t\t}\n\t\t}\n\t}\n\n\t\/**\n\t * Create a Parameters attribute on the HTTP Exchange.\n\t *\n\t * @param exchange\n\t *            HttpExchange to contain the attribute\n\t * @return copy of the attribute.\n\t *\/\n\tprivate Map&lt;String, Object> createParametersOnExchange(final HttpExchange exchange)\n\t{\n\t\texchange.setAttribute(\"parameters\", new HashMap&lt;String, Object>());\n\t\treturn ParameterFilter.getParametersFromExchange(exchange);\n\t}\n\n\t\/**\n\t * Decode the Key Parameter from the URL\n\t *\n\t * @param param\n\t *            Array of parameters from the Key\/Value Pair\n\t * @return Key\n\t * @throws UnsupportedEncodingException\n\t *             Parameter 0 not in standard encoding.\n\t *\/\n\tprivate String decodeKey(final String&#91;] param) throws UnsupportedEncodingException\n\t{\n\t\tString key = null;\n\t\tif (param.length > 0)\n\t\t{\n\t\t\tkey = URLDecoder.decode(param&#91;0], System.getProperty(\"file.encoding\"));\n\t\t}\n\t\treturn key;\n\t}\n\n\t\/**\n\t * Decode the Value Parameter from the URL\n\t *\n\t * @param param\n\t *            Array of parameters from the Key\/Value Pair\n\t * @return Value\n\t * @throws UnsupportedEncodingException\n\t *             Parameter 1 not in standard encoding.\n\t *\/\n\tprivate String decodeValue(final String&#91;] param) throws UnsupportedEncodingException\n\t{\n\t\tString value = null;\n\t\tif (param.length > 1)\n\t\t{\n\t\t\tvalue = URLDecoder.decode(param&#91;1], System.getProperty(\"file.encoding\"));\n\t\t}\n\t\treturn value;\n\t}\n\n\t@Override\n\tpublic String description()\n\t{\n\t\treturn \"Parses the requested URI for parameters\";\n\t}\n\n\t@Override\n\tpublic void doFilter(final HttpExchange exchange, final Chain chain) throws IOException\n\t{\n\t\tthis.createParametersOnExchange(exchange);\n\t\tthis.parseGetParameters(exchange);\n\t\tthis.parsePostParameters(exchange);\n\t\tchain.doFilter(exchange);\n\t}\n\n\t\/**\n\t * parse the Get Parameters and add them to the HttpExchange as attribute\n\t * parameters\n\t *\n\t * @param exchange\n\t *            HTTPExchange for this URI request\n\t * @throws UnsupportedEncodingException\n\t *             Unable to decode\n\t *\/\n\tprivate void parseGetParameters(final HttpExchange exchange) throws UnsupportedEncodingException\n\t{\n\t\tfinal URI requestedUri = exchange.getRequestURI();\n\t\tfinal String query = requestedUri.getRawQuery();\n\t\tthis.parseQuery(query, exchange);\n\t}\n\n\t\/**\n\t * Parse the Post Parameter and add them to the HttpExcahnge as attribute\n\t * parameters\n\t *\n\t * @param exchange\n\t *            HTTPExchange for this URI request\n\t * @throws IOException\n\t *             Unable to parse request body\n\t *\/\n\tprivate void parsePostParameters(final HttpExchange exchange) throws IOException\n\t{\n\n\t\tif (\"post\".equalsIgnoreCase(exchange.getRequestMethod()))\n\t\t{\n\t\t\tfinal InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(), \"utf-8\");\n\t\t\tfinal BufferedReader br = new BufferedReader(isr);\n\t\t\tfinal String query = br.readLine();\n\t\t\tthis.parseQuery(query, exchange);\n\t\t}\n\t}\n\n\t\/**\n\t * Splits out the parameters from the URI\n\t *\n\t * @param query\n\t *            URI Query for this request\n\t * @param exchange\n\t *            HttpExchange containing the information on this request\n\t * @throws UnsupportedEncodingException\n\t *             Unable to decode\n\t *\/\n\tprivate void parseQuery(final String query, final HttpExchange exchange) throws UnsupportedEncodingException\n\t{\n\t\tif (query != null)\n\t\t{\n\t\t\tfinal String pairs&#91;] = query.split(\"&#91;\" + HttpConstants.AND_DELIMITER + \"]\");\n\n\t\t\tfor (final String pair : pairs)\n\t\t\t{\n\t\t\t\tthis.parseQueryPair(exchange, pair);\n\t\t\t}\n\t\t}\n\t}\n\n\t\/**\n\t * Takes a Key \/ Value Pair from the Query for parsing.\n\t *\n\t * @param exchange\n\t *            HttpExchange containing this query\n\t * @param pair\n\t *            String for the Key\/Value Pair\n\t * @throws UnsupportedEncodingException\n\t *             Pair encoded incorrectly.\n\t *\/\n\tprivate void parseQueryPair(final HttpExchange exchange, final String pair) throws UnsupportedEncodingException\n\t{\n\t\tfinal String param&#91;] = pair.split(\"&#91;\" + HttpConstants.EQUAL_DELIMITER + \"]\");\n\n\t\tfinal String key = this.decodeKey(param);\n\t\tfinal String value = this.decodeValue(param);\n\t\tthis.addParameter(exchange, key, value);\n\t}\n}\n<\/code><\/pre>\n\n\n\n<p>Now if you wanted to create a com.sun.net.httpserver.Filter that could halt the execution, you only need to not call chain.doFilter(exchange) in the doFilter() method, but you must handle the response for the HttpExchange then. Also if you want to do processing after the ContextHandlerInterface has been called, you simple call chain.doFilter(exchange) first in your doFilter() method and do your processing afterward.<\/p>\n\n\n\n<p>A few ideas of what you could do here:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Session Filter &#8211; attach a session object to the HttpExchange to persist data about a client.<\/li><li>Authentication Filter &#8211; verify authentication for the client<\/li><li>Role Filter &#8211; attach attributes indicating the roles a client has.<\/li><li>Embedded HTML Filter &#8211; prevent HTML code from being embedded.<\/li><\/ul>\n\n\n\n<p>Just a few of the examples of things you could easily do.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We discussed the HTTP Server ContextHandler in a Jar&nbsp;one of the methods was ContextHandlerInterface.getFilters() this method returns a list of Filters to apply to incoming HTTP Requests. &nbsp;We subclass&nbsp;com.sun.net.httpserver.Filter for these classes. These can be used to do processing on the request and add attributes to the HTTP Exchange. Filters can block a particular call [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1902,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[459],"tags":[],"series":[226],"class_list":["post-1932","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java_http","series-http-server-in-a-jar"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1","jetpack-related-posts":[{"id":1911,"url":"https:\/\/www.mymiller.name\/wordpress\/java_http\/http-server-contexthandler-jar\/","url_meta":{"origin":1932,"position":0},"title":"HTTP Server ContextHandler in a Jar","author":"Jeffery Miller","date":"November 21, 2025","format":false,"excerpt":"Last time I showed you how to create a basic HTTP Server that you can put into a JAR easily. \u00a0Today I'm going to show you how to extend that to include a ContextHandler and AbstractContextHandler to make it easier to create Handlers for your HTTP Server. \u00a0If you remember\u2026","rel":"","context":"In &quot;Java HTTP&quot;","block_context":{"text":"Java HTTP","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java_http\/"},"img":{"alt_text":"filters","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":1906,"url":"https:\/\/www.mymiller.name\/wordpress\/java_http\/http-server-command-handler-in-a-jar\/","url_meta":{"origin":1932,"position":1},"title":"HTTP Server Command Handler in a Jar","author":"Jeffery Miller","date":"November 24, 2025","format":false,"excerpt":"Today, I'm going to share with you a command handler for the HTTP Server I presented previously. \u00a0This is a handler to extend the abilities of that HTTP Server in a Jar to provide you the ability to stop, restart and get status of it, if needed. WARNING: This is\u2026","rel":"","context":"In &quot;Java HTTP&quot;","block_context":{"text":"Java HTTP","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java_http\/"},"img":{"alt_text":"filters","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3438,"url":"https:\/\/www.mymiller.name\/wordpress\/spring\/architecting-with-spring-and-spring-cloud\/","url_meta":{"origin":1932,"position":2},"title":"Architecting with Spring and Spring Cloud","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Building a Multi-Service Architecture with Spring 3.1.x and Spring Cloud: Unlocking the Power of Microservices In the ever-evolving landscape of software development, microservices have emerged as a powerful architectural paradigm, enabling organizations to build scalable, resilient, and agile applications. Spring, a widely adopted Java framework, provides a comprehensive suite of\u2026","rel":"","context":"In &quot;Spring&quot;","block_context":{"text":"Spring","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/field-5236879_640.jpg?fit=640%2C360&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/field-5236879_640.jpg?fit=640%2C360&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/field-5236879_640.jpg?fit=640%2C360&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":1901,"url":"https:\/\/www.mymiller.name\/wordpress\/java_http\/http-server-jar\/","url_meta":{"origin":1932,"position":3},"title":"HTTP Server in your Jar","author":"Jeffery Miller","date":"November 20, 2025","format":false,"excerpt":"I recently had the need to be able to access a couple of files from a number of computers and didn't want to setup network shares and things. \u00a0These were a simple text files, that I was logging information into. However I was going to be moving around a number\u2026","rel":"","context":"In &quot;Java HTTP&quot;","block_context":{"text":"Java HTTP","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java_http\/"},"img":{"alt_text":"filters","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/09\/http-875180_640.jpg?fit=640%2C452&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3826,"url":"https:\/\/www.mymiller.name\/wordpress\/spring-gateway\/resilient-gateways-implementing-circuit-breakers-for-spring-data-rest-services-with-spring-cloud-gateway\/","url_meta":{"origin":1932,"position":4},"title":"Resilient Gateways: Implementing Circuit Breakers for Spring Data REST Services with Spring Cloud Gateway","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In a microservice architecture, services inevitably encounter transient failures \u2013 network hiccups, temporary overload, or slow responses from dependencies. Without proper handling, these failures can cascade, leading to a degraded user experience and even system-wide outages. This is where the circuit breaker pattern comes into play, providing a mechanism to\u2026","rel":"","context":"In &quot;Spring Gateway&quot;","block_context":{"text":"Spring Gateway","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring-gateway\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8314612_640.jpg?fit=640%2C480&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3922,"url":"https:\/\/www.mymiller.name\/wordpress\/spng_security\/beyond-rbac-spring-security-6-oauth-2-1-and-the-zero-trust-evolution\/","url_meta":{"origin":1932,"position":5},"title":"Beyond RBAC: Spring Security 6, OAuth 2.1, and the Zero-Trust Evolution","author":"Jeffery Miller","date":"November 19, 2025","format":false,"excerpt":"The journey to Zero Trust (ZT) is an ongoing architectural evolution, not a single deployment. While the foundational principles\u2014never trust, always verify\u2014are clear, implementing them in a distributed microservice environment requires rigorous adherence to modern standards. For Spring architects and developers, Spring Security 6 and the Spring Authorization Server provide\u2026","rel":"","context":"In &quot;Spring Security&quot;","block_context":{"text":"Spring Security","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spng_security\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/coding-1841550_1280.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/coding-1841550_1280.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/coding-1841550_1280.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/coding-1841550_1280.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/11\/coding-1841550_1280.avif 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/1932","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=1932"}],"version-history":[{"count":5,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/1932\/revisions"}],"predecessor-version":[{"id":2913,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/1932\/revisions\/2913"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/1902"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=1932"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=1932"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=1932"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=1932"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}