title: Spring Boot 1.4.3 / servlet api 3.1 Request cannot be cast to custom CustomServletRequestWrapper which extends standard HttpServletRequestWrapper
body: <p>I have implemented a custom servlet request wrapper which extends standard <code>HttpServletRequestWrapper</code> for XSS security vulnerabilities.</p>
  
  <p>However when I hit my application URL configured via Spring Boot 1.4.3 both (Jetty or Undertow) display error message as :</p>
  
  <pre><code>Request cannot be cast to com.example.rest.security.api.DemoServletRequestWrapper.
  </code></pre>
  
  <p>Not sure what is causing this issue as my custom servlet request wrapper is extending standard <code>HttpServletRequestWrapper</code>.</p>
  
  <p>I have tried both with latest Jetty and Undertow spring boot starters. However I still get similar exception stack trace message.</p>
  
  <p>Any pointers as How to resolve this issue and what is the root cause of the issue?</p>
  
  <p>My application is a Spring Boot RESTFul web service flat jar.</p>
  
  <p>Below are my Spring Boot / Jetty dependencies.</p>
  
  <pre><code>dependencies {
      compile('org.springframework.boot:spring-boot-starter')
      compile("org.springframework.boot:spring-boot-starter-web:1.4.3.RELEASE")
      compile("org.springframework.boot:spring-boot-starter-jetty:1.4.3.RELEASE")
  </code></pre>
  
  <p>OR Undertow</p>
  
  <pre><code>    compile("org.springframework.boot:spring-boot-starter-undertow:1.4.3.RELEASE")
      compile("org.springframework.boot:spring-boot-starter-jersey:1.4.3.RELEASE")
      compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
      testCompile('org.springframework.boot:spring-boot-starter-test')
  }
  </code></pre>
  
  <p>Below is Jetty stack trace</p>
  
  <pre><code>2017-01-12 11:17:28.054  INFO 6340 --- [main] com.example.DemoApplication              : Started DemoApplication in 5.198 seconds (JVM running for 5.771)
  2017-01-12 11:19:15.505  WARN 6340 --- [qtp1991294891-13] o.eclipse.jetty.servlet.ServletHandler   : /demo/v1.0/api/gateway
  
  java.lang.ClassCastException: org.eclipse.jetty.server.Request cannot be cast to com.example.api.rest.security.api.DemoServletRequestWrapper
      at com.example.api.filters.XSSFilter.doFilter(XSSFilter.java:30) ~[classes!/:na]
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) ~[jetty-servlet-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) ~[jetty-servlet-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) ~[jetty-servlet-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) ~[jetty-servlet-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) ~[jetty-servlet-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582) [jetty-servlet-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) [jetty-security-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512) [jetty-servlet-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.Server.handle(Server.java:534) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) [jetty-server-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) [jetty-io-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) [jetty-io-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) [jetty-io-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) [jetty-util-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) [jetty-util-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) [jetty-util-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) [jetty-util-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) [jetty-util-9.3.14.v20161028.jar!/:9.3.14.v20161028]
      at java.lang.Thread.run(Unknown Source) [na:1.8.0_112]
  </code></pre>
  
  <p>Below is undertow stack trace</p>
  
  <pre><code>2017-01-11 16:26:15.486  INFO 12372 --- [main] com.example.DemoApplication              : Started DemoApplication in 3.805 seconds (JVM running for 4.325)
  2017-01-11 16:26:24.680 ERROR 12372 --- [XNIO-3 task-1] io.undertow.request                      : UT005023: Exception handling request to /demo/v1.0/api/gateway
  
  java.lang.ClassCastException: io.undertow.servlet.spec.HttpServletRequestImpl cannot be cast to com.example.api.rest.security.api.DemoServletRequestWrapper
      at com.example.api.filters.XSSFilter.doFilter(XSSFilter.java:30) ~[classes!/:na]
      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:285) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:264) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:175) ~[undertow-servlet-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.server.Connectors.executeRootHandler(Connectors.java:207) ~[undertow-core-1.3.25.Final.jar!/:1.3.25.Final]
      at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:802) [undertow-core-1.3.25.Final.jar!/:1.3.25.Final]
      at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_112]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_112]
      at java.lang.Thread.run(Unknown Source) [na:1.8.0_112]
  </code></pre>
  
  <p>Below is the source code.</p>
  
  <pre><code>/* Main Spring Boot application */
  
  @SpringBootApplication
  @Import(AppConfig.class)
  public class DemoApplication {
  
      public static void main(String[] args) {
          SpringApplication.run(DemoApplication.class, args);
      }
  
  }
  </code></pre>
  
  <p>App configuration with XSS Filter registration bean</p>
  
  <pre><code>@Configuration
  public class AppConfig {
  
      @Bean
      public FilterRegistrationBean xssFilter() {
          FilterRegistrationBean registration = new FilterRegistrationBean();
          XSSFilter xssFilter = new XSSFilter();
          registration.setFilter(xssFilter);
          registration.setName("XSSFilter");
          registration.addUrlPatterns("/v1.0/*");
          return registration;
      }
  }
  </code></pre>
  
  <p>Spring Boot Jersey Config for RESTful services implementation</p>
  
  <pre><code>@Component
  public class JerseyConfig extends ResourceConfig {
      public JerseyConfig() {
          registerEndpoints();
      }
  
      private void registerEndpoints() {
          register(DemoEndPoint.class);
      }
  }
  </code></pre>
  
  <p>Demo End Point REST service</p>
  
  <pre><code>@Component
  @Path("/api")
  public class DemoEndPoint {
      @GET
      @Path("/gateway")
      public String test() {
          return "API Gateway!";
      }
  }
  </code></pre>
  
  <p>XSS Filter implementation</p>
  
  <pre><code>public class XSSFilter implements Filter {
  
      private static final Logger LOGGER = LoggerFactory.getLogger(XSSFilter.class);
  
      @Override
      public void init(final FilterConfig filterConfig) throws ServletException {
      }
  
      @Override
      public void doFilter(final ServletRequest request, final ServletResponse response,
                           final FilterChain chain) throws IOException, ServletException
      {
          LOGGER.debug("doFilter - Entry");
          LOGGER.debug("doFilter - Checking http request body for XSS vulnerabilities");
          final DemoServletRequestWrapper requestWrapper = (DemoServletRequestWrapper)request;
          LOGGER.debug("doFilter - Request body = {}", requestWrapper.getBody());
          final String body = EncodeHtmlContent(requestWrapper.getBody());
          LOGGER.debug("doFilter - Request body encoded to {}", body);
          requestWrapper.setBody(body);
          chain.doFilter(requestWrapper, response);
   }
  }
  
  /* DemoServletRequestWrapper extends HttpServletRequestWrapper */
  
  I have implemented all the methods of standard `HttpServletRequestWrapper` in this class. For brevity I am displaying only one method in my stack query.
  
  public class DemoServletRequestWrapper extends HttpServletRequestWrapper implements
          HttpServletRequest {
  
      private String body;
  
      private static final Logger LOGGER = LoggerFactory.getLogger(DemoServletRequestWrapper.class);
  
      public MifidServletRequestWrapper(final HttpServletRequest request) throws IOException {
          super(request);
          final StringBuilder stringBuilder = new StringBuilder();
          BufferedReader bufferedReader = null;
          try {
              final InputStream inputStream = request.getInputStream();
              if (inputStream != null) {
                  bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                  final char[] charBuffer = new char[128];
                  int bytesRead = -1;
                  while ((bytesRead = bufferedReader.read(charBuffer)) &gt; 0) {
                      stringBuilder.append(charBuffer, 0, bytesRead);
                  }
              } else {
                  stringBuilder.append("");
              }
          } catch (final IOException ex) {
              LOGGER.error("Error whilst creating the DemoServletRequestWrapper", ex);
              throw ex;
          } finally {
              if (bufferedReader != null) {
                  try {
                      bufferedReader.close();
                  } catch (final IOException ex) {
                      LOGGER.error("Error whilst creating the DemoServletRequestWrapper", ex);
                      throw ex;
                  }
              }
          }
          body = stringBuilder.toString();
  
      }
  </code></pre>
  
  <p>Implemented all the methods and able to compile my build successfully</p>