I have issue with UTF-8 characters. I've tried many solutions, but nothing is working for me. What I have right now:
Tomcat (server.xml):
<Connector URIEncoding="UTF-8" useBodyEncodingForURI="true" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
Base configuration class:
public class HomeInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebSecurityConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebMvcConfiguration.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8"); // forcing UTF-8
filter.setForceEncoding(true);
return new Filter[] { filter };
}
}
WebMvcConfiguration class which contains Thymeleaf configuration:
#Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8"); // forcing UTF-8
viewResolver.setContentType("text/html; charset=UTF-8");
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] { ".html", ".xhtml" });
return viewResolver;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setCharacterEncoding("UTF-8"); // forcing UTF-8
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCacheable(true);
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}
WebSecurityConfig which contains the rest of the configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().anonymous().antMatchers("/login**", "/*.js", "/*.css", "/*.svg").permitAll().anyRequest().authenticated()
.antMatchers("/login**").permitAll().and().formLogin().loginPage("/login").loginProcessingUrl("/login").usernameParameter("username")
.passwordParameter("password").defaultSuccessUrl("/", true).permitAll().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout").deleteCookies("JSESSIONID")
.invalidateHttpSession(true).permitAll();
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8"); // another forcing UTF-8
filter.setForceEncoding(true);
http.addFilterBefore(filter, CsrfFilter.class);
}
all html pages contain:
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
before I've added Thymeleaf and used jsp I've been able to display special characters
also checked that all files (.html) are encoded with UTF-8
Eclipse settings changed to keep everything in UTF-8
checked probably all answers on stackoverflow related to this issue and verified all higher ranked answers (including this, this and that)
checked Thymeleaf messaging solution (some stack question for that)
escaped characters \u0119 are displayed as they are - \u0119
created new project with same pom.xml, Spring/Thymeleaf configuration
And still instead of polish
ąęłźżńłó
I have
???????ó
displayed on page. Any ideas?
Unfortunatelly I don't have
web.xml
and whole configuration uses annotations. I can't control
Filter
classes order - see can use #Order annotation
Used technologies: Spring Framework 5.1.6, Spring Security 5.1.5, Thymeleaf 3.0.11, Thymeleaf Spring security4 3.0.4, Maven 4, Tomcat 9.
Unfortunatelly I have to answer my own question.
To read UTF-8 data from properties file, just use encoding property
#Component
#PropertySource(value = "classpath:config/data.properties", encoding = "UTF-8")
basically what helped was adding some additional method calls to the configureViewResolvers method:
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8"); // <- this was added
resolver.setForceContentType(true); // <- this was added
resolver.setContentType("text/html; charset=UTF-8"); // <- this was added
registry.viewResolver(resolver);
}
and additionaly in configure(HttpSecurity http) method I've changed the way how filter is added to this:
#Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
http.authorizeRequests().anyRequest().anonymous()
.antMatchers("/login**", "/*.js", "/*.css", "/*.svg" ).permitAll()
// ... some other config
.invalidateHttpSession(true)
.permitAll()
.and()
.addFilterBefore(filter, CsrfFilter.class); // <- this was added
}
So this might seem very remedial, but have you navigated to the directory structure, right clicked the folder containing your pages, and selecting refresh?
I don't know what IDE you're using, but in the past I have had to manually go into Eclipse and refresh the package containing the static content.
If you don't do this, it won't pick up on the changes.
Related
I'm trying to pass some information from a browser to my server and end up having '????' symbols. I thoroughly searched for this problem on the Internet and StackOverFlow but in the end nothing helped me. My assumption is Thymeleaf/Spring continues to use ISO_8859_1 charset instead of UTF-8.
DispatcherServlet(CharacterEncodingFilter):
public class DispatcherServlet extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
public void onStartup(ServletContext aServletContext) throws ServletException {
super.onStartup(aServletContext);
registerCharacterEncodingFilter(aServletContext);
registerHiddenFieldFilter(aServletContext);
}
private void registerHiddenFieldFilter(ServletContext aContext) {
aContext.addFilter("hiddenHttpMethodFilter",
new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null, true, "/*");
}
private void registerCharacterEncodingFilter(ServletContext aContext) {
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST,
DispatcherType.FORWARD);
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
FilterRegistration.Dynamic characterEncoding = aContext.addFilter("characterEncoding",
characterEncodingFilter);
characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
}
}
My Configuration:
public class ApplicationConfiguration implements WebMvcConfigurer {
private final ApplicationContext applicationContext;
private final Environment environment;
#Autowired
public ApplicationConfiguration(ApplicationContext applicationContext,
Environment environment) {
this.applicationContext = applicationContext;
this.environment = environment;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
resourceHandlerRegistry.addResourceHandler("/resources/**").
addResourceLocations("/resources/");
}
// Themyleaf resolver,engine etc
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("UTF-8");
resolver.setTemplateMode("HTML5");
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
engine.addDialect(new SpringSecurityDialect());
engine.setEnableSpringELCompiler(true);
return engine;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setContentType("text/html; charset=UTF-8");
resolver.setCharacterEncoding("UTF-8");
registry.viewResolver(resolver);
}
}
As I've already said, I'm trying to make Spring/Thymeleaf use UTF-8 charset instead of the standard one. Certainly I could use something like
byte[] bytes = content.getBytes(StandardCharsets.ISO_8859_1);
content = new String(bytes, StandardCharsets.UTF_8);
but I'd like to have it done by Spring/Thymeleaf if it's possible.
UPD: Whatever the input data is I always see '???' in the console. For instance: 'Текстовая строка123' produces '???µ???????????°?? ???????????°123' (except for Non Cyrillic symbols)
I am new to spring boot MVC app development. I have a new application, that I set up through Maven, in which I am trying to import jquery and bootstrap. I imported both through Maven as Jar files. They reside in Java Resources->Libraries->Maven Dependencies.
I am using spring framework 5.3.22 and spring security 5.7.3
When I run my site, I can see the jquery and bootstrap files are added in the Network tab, but I get the following errors:
"Refused to execute script from [website url] because its MIME type
('text/html') is not executable, and strict MIME type checking is
enabled."
And
"Refused to apply style from [website url] because its
MIME type ('text/html') is not a supported stylesheet MIME type, and
strict MIME checking is enabled."
On my JSP page, I include the files like this:
<link href="webjars/bootstrap/5.2.0/css/bootstrap.min.css" rel="stylesheet" >
<script src="webjars/jquery/3.6.1/jquery.min.js" type="text/javascript"></script>
<script src="webjars/bootstrap/5.2.0/js/bootstrap.min.js" type="text/javascript"></script>
My Servlet config looks like this:
public class MySpringMvcDispatcherServeletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
//return DemoAppConfig.java class
return new Class[] {DemoAppConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
#Configuration
#EnableWebSecurity
public class DemoSecurityConfig {
#Bean
public InMemoryUserDetailsManager userDetailsManager() {
System.out.println("======>> Add Details manager");
//add in memory users/roles
}
#Bean
public CorsConfigurationSource corsConfigurationSource(){
System.out.println("======>> Add CORS");
CorsConfiguration corsConfiguration = new CorsConfiguration();
// Below config will allow only following origines from web browser
corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:8080/"));
// Whether user credentials are supported. By default, do not support
// If you want to allow credentials then set it true
corsConfiguration.setAllowCredentials(false);
// below will not allow DELETE methods, if you want then add DELETE also
corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "OPTION"));
// Below will set allowed headers list, Other headers will not be supported
corsConfiguration.setAllowedHeaders(Arrays.asList("accept", "authorization", "apikey", "tenantId"));
UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
// This will register above configurations on all resources from the root
// If you want different rules for different resources then create separate configuration
// and register on separate resource path uri
corsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return corsConfigurationSource;
}
#Bean
public WebSecurityCustomizer webSecurityCustomizer() {
// Ignore resources for any check
System.out.println("======>> Add web Customizer");
return (web) -> web.ignoring().antMatchers("/webjars/**","/resources/**", "/static/**", "/css/**", "/js/**", "/img/**", "/icon/**");
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
System.out.println("======>> Add Security Chain");
return http
.authorizeRequests(configurer ->
configurer
.antMatchers("/webjars/**","/resources/**", "/static/**", "/css/**", "/js/**", "/img/**", "/icon/**").permitAll()
.anyRequest().authenticated())
.formLogin(configurer ->
configurer
.loginPage("/showMyLoginPage")
.loginProcessingUrl("/authenticateTheUser")
.permitAll())
.build();
}
}
I was able to do this by overriding addResrouceHandlers. In my DemoAppConfig file, which implements WebMvcConfigurer, I add this code:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.jason.springsecurity.demo")
public class DemoAppConfig implements WebMvcConfigurer{
//define bean for ViewResolver
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
System.out.println("================>Calling addResourceHandlers");
//my libraries
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
//webjars
if (!registry.hasMappingForPattern("/webjars/**")) {
registry.addResourceHandler("/webjars/**").addResourceLocations(
"classpath:/META-INF/resources/webjars/");
}
}
}
I can then add the files to my Views like this:
<link href="webjars/bootstrap/5.2.0/css/bootstrap.min.css" rel="stylesheet" >
<script src="webjars/jquery/3.6.1/jquery.min.js"></script>
<script src="webjars/bootstrap/5.2.0/js/bootstrap.min.js"></script>
I currently have a Spring Boot application that is using React JS for the front end. I'm running inside Visual Studio, and via webpack, I'm compiling resources and outputting them to a Maven target folder. You can see the structure of the directory with the Java classes sitting inside the 'classes' folder and the client application sitting now inside the webapp folder - notice the index.html.
As this is a single page application I only need this page to resolve. As such my controller is configured to return the index file.
#SpringBootApplication
public class AdminApplication
{
public static void main( String[] args )
{
SpringApplication.run( AdminApplication.class, args );
}
}
#Controller
public class DefaultController
{
#RequestMapping( "/**" )
public ModelAndView reactApp()
{
return new ModelAndView( "index" );
}
}
Now. My problem comes with telling my view resolver to talk to this directory.
As you can see from the commented code, I've tried only a couple of hundred options for trying to get it to resolve the view. I've got the full file path to my project directory available on the documentRoot so if necessary and thought potentially I would need that.
I've put a breakpoint in the controller and this definitely does get hit, it just returns a 404 when trying to find the relevant view each time. Any guidance on what my viewResolver might need to look like appreciated. I can see there's a couple of Classes that may or may not be correct:
e.g. SpringResourceTemplateResolver and ClassLoaderTemplateResolver - not sure on which of these is most relevant for my requirements
#EnableWebMvc
#Configuration
public class MvcConfig implements WebMvcConfigurer,ApplicationContextAware {
private ApplicationContext context;
#Value("${server.document-root:}")
private String documentRoot;
#Override
public void setApplicationContext( ApplicationContext applicationContext ) {
this.context = applicationContext;
}
// private ITemplateResolver htmlTemplateResolver() {
// SpringResourceTemplateResolver resolver = new
// SpringResourceTemplateResolver();
// resolver.setApplicationContext(applicationContext);
// resolver.setPrefix(documentRoot);
// resolver.setCacheable(false);
// resolver.setTemplateMode(TemplateMode.HTML);
// return resolver;
// }
// #Bean
// public SpringResourceTemplateResolver templateResolver() {
// SpringResourceTemplateResolver templateResolver = new
// SpringResourceTemplateResolver();
// templateResolver.setPrefix( "/webapp/" );
// templateResolver.setCacheable(false);
// templateResolver.setSuffix(".html");
// templateResolver.setTemplateMode("HTML");
// return templateResolver;
// }
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(context);
resolver.setPrefix("templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
// public ITemplateResolver templateResolver() {
// ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
// templateResolver.setPrefix("templates/");
// templateResolver.setCacheable(false);
// templateResolver.setSuffix(".html");
// templateResolver.setTemplateMode(TemplateMode.HTML);
// templateResolver.setCharacterEncoding("UTF-8");
// return templateResolver;
// }
}
you don't need MvcConfig
just set the static-locations property in src/main/resources/application.properties to spring.resources.static-locations=classpath:/webapp/
map all possible request to your index-page like:
#GetMapping({"/index","/","/home"})
public String reactApp()
{
return "/index.html";
}
optional you could redirect the requests to your index-page
#GetMapping({"/index","/","/home"})
public String reactApp()
{
return "redirect:/index.html";
}
You don't need the MvcConfig class, Spring boot auto-configure the view resolver. All you have to do is to put your templates to the src/main/resources/templates/ directory and make a simple controller mapping like this
#RequestMapping(value = "/")
public String index() {
return "index";
}
in your home controller.
You can also check out this React.js and Spring example
you will need to configure your resource handler, that way:
#Configuration
public class StaticResourceConfiguration implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("file:/path/to/dir/webapp/");
}
}
Notice, that in unix you will use file:/ and for windows
file:///C:/path/to/dir/webapp/
And then redirect the/ to index.html
#RequestMapping
#RestController
public class IndexEndpoint {
#GetMapping("/")
public String reactApp() {
return "/index.html";
}
}
I have tested it on a MacOS and it worked prefect.
I'm trying to develop a spring MVC project which has a index.jsp file as it's view. I searched and found I should do this by the help of two below configuration classes:
public class MainInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
public static HashMap<String, String> response_code = new HashMap<String, String>();
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { MainConfiguration.class,
WebSocketConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
Security.addProvider(new BouncyCastleProvider());
servletContext.addListener(new MainContextListener());
}
}
and this is MainConfiguration class:
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = "-----")
public class MainConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/Content/**")
.addResourceLocations("/Content/");
registry.addResourceHandler("/Scripts/**")
.addResourceLocations("/Scripts/");
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver
= new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
I've configured my project to run on tomcat web-server inside intellij. but when index.jsp is directly in path : webapp/index.jsp it will be opened in browser after running the program but when I move it to a subfolder it doesn't.
Shouldn't this part of code give the address to spring so it find the url and don't give a 404 error?
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
You need to annotate your MainConfiguration.java with #Configuration. Also, you require to register an instance of the DispatcherServlet in the servlet context. Actually, you can refer - spring mvc with jsp example for detailed configurations.
I have a simple page called headers.jsp in my Spring-MVC (4.1.5.RELEASE) web-app which i would like to call up from my index page like this:
<body>
<c:url value="/headers" var="headersUrl1"/>
<c:url value="/headers.jsp" var="headersUrl2"/>
<c:url value="/headers.jspx" var="headersUrl3"/>
<ul>
<li>Works!</li>
<li>Does not work!</li>
<li>Does not work!</li>
</ul>
The first url (to /headers) works fine but the other two (with suffix .jsp/jspx) do not; result is a 404. I have a need for the links to work (in real life they come from a legacy database which i have to use). I have spent quite some time googling but found no solution as yet.
The requests to links are handled by the following controller code:
#Controller
public class HeadersViewController {
#RequestMapping(value = {"/headers"}, method = RequestMethod.GET)
public String getHeadersPage() {
return "headers";
}
#RequestMapping(value = {"/headers**"}, method = RequestMethod.GET)
public String getHeaderPages() {
return "headers";
}
#RequestMapping(value = {"/headers.jspx"}, method = RequestMethod.GET)
public String getHeaderPageJspx() {
return "headers";
}
#RequestMapping("/{name}.jspx")
public String getPageByName(#PathVariable("name") String name) {
return name;
}
}
None of the controller methods get called when requesting /headers.jsp or /headers.jspx.
Strangely enough when using spring-test and mock-mvc they do get fired and tests to check the mentioned url`s passes.
Any help greatly appreciated! The rest of the config code is given below.
Dispatcherservlet init:
public class DispatcherServletInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { SecurityConfiguration.class, WebMvcConfiguration.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter() };
}
}
MvcConfiguration:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"nl.demo.web.controller"})
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/login");
registry.addViewController("/logout");
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/");
viewResolver.setSuffix(".jsp");
viewResolver.setOrder(0);
return viewResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Security config:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/images/**", "/js/**", "/css/**", "/fonts/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index")
.failureUrl("/login?error=1")
.permitAll()
.and()
.httpBasic()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout=1")
.permitAll();
}
#Autowired
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
String user = "test";
String password = "blabla";
String[] roleList = "USER,SUPERVISOR".split(",");
auth.inMemoryAuthentication()
.withUser(user)
.password(password)
.roles(roleList);
}
}
The most likely cause of your issue is that the *.jsp and *.jspx extensions are normally handled by the container. If you for example checkout tomcat's conf/web.xml you'll notice a configuration
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
Similar goes for other containers. That is why your tests are working, yet your real app request fail.
Your best option would be to implement a Filter, that will be mapped to the same pattern, and that will redirect the headers.jsp and headers.jspx, to be handled by the controller, while leaving the other requests to be processed by the container as they would normally be, you have an example at this question
The problem is that your servlet is mapped to / and not to /*. / is a special mapping meaning that Spring MVC DispatcherServlet receives all requests that have not been managed by anything else.
As JSP and JSF are automatically registered servlets, the servlet container tries to pass the request to a JSP (resp. JSF) file and if it does not find it immediately sends a 404 and does not try to pass it to the DispatcherServlet.
You should map the dispatcher servlet to /*. But beware in that case, all URL will be given to the dispatcher servlet, and you will have to do a special treatment for serving static resources : you must add an override for addResourceHandlers to your Spring MVC configuration file (extract from Spring Framework Reference Manual - Serving of static resources) :
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/public-resources/");
}