2015-06-08 4 views
2

У меня есть простая страница headers.jsp в моем веб-приложении Spring-MVC (4.1.5.RELEASE), который я хотел бы вызвать с моей индексной страницы как это:Ссылка Spring MVC с суффиксом .jsp/.jsp возвращает 404

<body> 
<c:url value="/headers" var="headersUrl1"/> 
<c:url value="/headers.jsp" var="headersUrl2"/> 
<c:url value="/headers.jspx" var="headersUrl3"/> 
<ul> 
    <li><a href="${headersUrl1}">Works!</a></li> 
    <li><a href="${headersUrl2}">Does not work!</a></li> 
    <li><a href="${headersUrl3}">Does not work!</a></li> 
</ul> 

Первый URL (в/заголовки) работает нормально, но два других (с суффиксом .jsp/JSPX) нет; результатом является 404. Мне нужно, чтобы ссылки работали (в реальной жизни они исходят из старой базы данных, которую я должен использовать). Я потратил довольно много времени на поиски в Google, но пока не нашел решения. Запросов к ссылкам обрабатываются с помощью следующего кода контроллера:

@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; 
} 
} 

Ни один из методов контроллера не вызываются при запросе /headers.jsp или /headers.jspx.

Как ни странно, при использовании весенних испытаний и mock-mvc они увольняются и проверяют указанные урны. Любая помощь очень ценится! Остальная часть кода конфигурации приведена ниже.

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(); 
} 
} 

конфигурации безопасности:

@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); 
} 
} 
+0

Вы можете попробовать суффикс '.html' в' c: url' и попробовать без изменения сопоставления контроллера. –

+0

Да, это работает, также довольно странно, но мне нужны .jsp и .jspx suffix-es –

ответ

1

Наиболее вероятной причиной вашей проблемы является то, что *.jsp и *.jspx расширения, как правило, обрабатываются контейнером. Если вы, например, контроль запуска Tomcat conf/web.xml вы заметите конфигурацию

<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> 

Похожие идет для других контейнеров. Вот почему ваши тесты работают, но ваш настоящий запрос приложения не работает.

Ваш лучший вариант - реализовать фильтр, который будет сопоставлен с одним и тем же шаблоном, и перенаправляет headers.jsp и headers.jspx, которые будут обрабатываться контроллером, оставив другие запросы обрабатываться контейнером как это обычно бывает, у вас есть пример на этом примере. question

+0

Это работает для меня, я реализовал новый фильтр, который перенаправляет запрос на servletPath, если servletPath завершает работу .jsp/.jspx , Добавляя @WebFilter (urlPatterns = "/ *") в качестве аннотации, фильтр и добавление его в getServletFilters диспетчера init делает трюк! Большое спасибо! –

+0

np, рад, что это помогло –

0

Проблема в том, что ваш сервлет отображается на /, а не на /*. / - это специальное сопоставление, означающее, что Spring MVC DispatcherServlet получает все запросы , которыми еще не управляли.

Поскольку JSP и JSF являются автоматически зарегистрированными сервлетами, контейнер сервлетов пытается передать запрос в файл JSP (или JSF), и если он не находит его сразу, он отправляет 404 и не пытается передать его в DispatcherServlet.

Необходимо отобразить сервлет диспетчера на /*.Но будьте осторожны в этом случае, все URL-адреса будут переданы сервлет диспетчера, и вам придется делать специальное лечение для обслуживания статических ресурсов: вы должны добавить переопределение для addResourceHandlers в конфигурационный файл Spring MVC (извлечение из справочного руководства Spring Framework - Обслуживание статических ресурсов):

@Override 
public void addResourceHandlers(ResourceHandlerRegistry registry) { 
    registry.addResourceHandler("/resources/**").addResourceLocations("/public-resources/"); 
} 
+0

Сопоставление диспетчера с/* не работает для меня, потому что все остальные jsp не отображаются. –

Смежные вопросы