Spring 3.2 - 切换到JavaConfig后无法解析视图名称

时间:2014-03-09 17:08:32

标签: java spring spring-mvc controller dispatcher

我刚刚使用Spring MVC 3.2.3和Spring Security 3.2.1将我的所有xml配置文件转换为JavaConfig。我遇到了一些问题,其中带有@ElementCollection(fetch = FetchType.EAGER)注释成员的实体仍然没有被提取(我的XML配置没有问题)我不得不添加@Fetch(FetchMode.JOIN)注释。但是,我仍然无法从控制器中检索数据。

我的许多请求都得到后端的完全处理,但是当他们从我的控制器方法返回时,我收到错误" HTTP状态500 - 无法解析名称为&#39的视图; XXX'在名为' dispatcher'"的servlet中。问题是,我只有3个视图:登录,索引和管理员。索引页面是一个单页面站点,它对控制器进行了大量的AJAX调用,其中大部分都是使用@RequestBody向DTO解组JSON请求,并且所有这些请求都直接使用@ResponseBody编写响应并使用Jackson转换为JSON。这在过去总是有效 - 控制器方法应该只是REST端点,但现在,调度程序servlet想要将视图与几乎所有的请求相关联,但不是全部。我不确定如何告诉视图解析器或调度程序servlet仅将index,admin和login视为视图,并将其他所有内容视为简单的REST请求。任何帮助,将不胜感激!这是我的配置:

Root Config:

@Configuration
@ComponentScan(value = "x.configuration", excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, value = RootConfig.class))
public class RootConfig {}

SecurityInitializer:

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {}

WebApp初始化程序:

public class WebAppInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{
            "/rest/*",
            "/index.html",
            "/login.html",
            "/admin.html",
            "/index/*",
            "/login/*",
            "/admin/*"
        };
    }

    @Override
    protected Filter[] getServletFilters() {
        OpenEntityManagerInViewFilter openEntityManagerInViewFilter = new OpenEntityManagerInViewFilter();
        openEntityManagerInViewFilter.setBeanName("openEntityManagerInViewFilter");       
        openEntityManagerInViewFilter.setPersistenceUnitName("HSQL");
        return new javax.servlet.Filter[]{openEntityManagerInViewFilter};
    }
}

Spring MVC config:

@Configuration
@EnableWebMvc
@EnableTransactionManagement
{@ComponentScan.Filter(type= FilterType.ANNOTATION, value=Controller.class)})
@ComponentScan(basePackages = "x.clients")
public class SpringMvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public InternalResourceViewResolver setupViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setViewNames(new String[] {"login", "index", "admin"});
        return viewResolver;
    }

    @Bean
    public DefaultAnnotationHandlerMapping getDefaultAnnotationHandlerMapping() {
        DefaultAnnotationHandlerMapping handlerMapping = new DefaultAnnotationHandlerMapping();
        handlerMapping.setAlwaysUseFullPath(true);
        handlerMapping.setDetectHandlersInAncestorContexts(true);
        return handlerMapping;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(getMappingJacksonHttpMessageConverter());
        super.configureMessageConverters(converters);
    }


    @Bean 
    public JacksonAnnotationIntrospector getJacksonAnnotationIntrospector(){
        return new JacksonAnnotationIntrospector();
    }

    @Bean
    public ObjectMapper getObjectMapper(){
        ObjectMapper mapper = new ObjectMapper();

        mapper.setAnnotationIntrospector(getJacksonAnnotationIntrospector());
        mapper.registerModule(new Hibernate4Module());
        return mapper;
    }

    @Bean MappingJackson2HttpMessageConverter getMappingJacksonHttpMessageConverter(){
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        messageConverter.setObjectMapper(getObjectMapper());

        return messageConverter;
    }

    @Bean
    public DefaultConversionService getDefaultConversionService(){
        return new DefaultConversionService();
    }
}

Spring Security Config:

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;
    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        AuthenticationProvider rememberMeAuthenticationProvider = getRememberMeAuthenticationProvider();
        TokenBasedRememberMeServices tokenBasedRememberMeServices = getTokenBasedRememberMeServices();

        List<AuthenticationProvider> authenticationProviders = new ArrayList<AuthenticationProvider>(2);
        authenticationProviders.add(rememberMeAuthenticationProvider);
        authenticationProviders.add(customAuthenticationProvider);
        AuthenticationManager authenticationManager = getAuthenticationManager(authenticationProviders);

        http
                .csrf().disable()
                .headers().disable()
                .addFilter(new RememberMeAuthenticationFilter(authenticationManager, tokenBasedRememberMeServices))
                .rememberMe().rememberMeServices(tokenBasedRememberMeServices)
                .and()
                .authorizeRequests()
                .antMatchers("/js/**", "/css/**", "/img/**", "/login", "/processLogin").permitAll()
                .antMatchers("/index.jsp", "/index.html", "/index").hasRole("USER")
                .antMatchers("/admin", "/admin.html", "/admin.jsp").hasRole("ADMIN")
                .and()
                .formLogin().loginProcessingUrl("/processLogin").loginPage("/login").failureUrl("/login").permitAll()
                .and()
                .logout().permitAll();
    }



    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**", "/css/**", "/img/**");
    }

    @Bean
    public AuthenticationManager getAuthenticationManager(List<AuthenticationProvider> authenticationProviders) {
        return new ProviderManager(authenticationProviders);
    }

    @Bean
    public TokenBasedRememberMeServices getTokenBasedRememberMeServices() {
        return new TokenBasedRememberMeServices("testKey", userDetailsService);
    }

    @Bean
    public AuthenticationProvider getRememberMeAuthenticationProvider() {
        return new org.springframework.security.authentication.RememberMeAuthenticationProvider("testKey");
    }

    protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }
}

我的所有控制器方法都可以通过URL模式/ rest //.

访问

以下控制器只返回枚举项列表并正常工作:

@Controller
@RequestMapping("/swterms")
public class SwTermsController {
    @RequestMapping(value = "/getSensorTypes", method = RequestMethod.GET)
    @ResponseBody
    public List<String> getSensorTypes() {
        List<String> sensorTypes = new ArrayList<String>();
        for (SensorTypes sensorType : SensorTypes.values()){
            sensorTypes.add(sensorType.getURI());
        }
        return sensorTypes;
    }
}

此控制器返回地图图层列表。我可以在调试模式中逐步完成所有内容都很好,但它会产生500错误:

@Controller
@RequestMapping("/map")
public class MapLayerController {

    @Autowired
    @Resource(name="mapLayers") private List<OpenLayersMapLayer> mapLayers;

    @RequestMapping(value = "/getLayerData", method = RequestMethod.GET)
    @ResponseBody
    public Map getMapLayers() {
        Map model = new HashMap();
        model.put("layers", this.mapLayers);
        return model;
    }   
}

以下是日志的相关部分:

 00:12:21,034 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.FilterChainProxy] - /rest/map/getLayerData at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
    00:12:21,034 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/logout'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/js/**'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/css/**'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/img/**'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/login'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/processlogin'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/index.jsp'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/index.html'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/index'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/admin'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/admin.html'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/admin.jsp'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] - Checking match of request : '/rest/map/getlayerdata'; against '/js/saic/jswe/admin/**'
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] - Public object - authentication not attempted
    00:12:21,035 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.FilterChainProxy] - /rest/map/getLayerData reached end of additional filter chain; proceeding with original chain
    00:12:21,041 (http-bio-8084-exec-77) DEBUG [org.springframework.web.servlet.DispatcherServlet] - DispatcherServlet with name 'dispatcher' processing GET request for [/swtc/rest/map/getLayerData]
    00:12:21,041 (http-bio-8084-exec-77) DEBUG [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] - Looking up handler method for path /map/getLayerData
    00:12:21,042 (http-bio-8084-exec-77) DEBUG [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] - Returning handler method [public org.springframework.ui.ModelMap x.clients.controllers.MapLayerController.getMapLayers(org.springframework.ui.ModelMap)]
    00:12:21,042 (http-bio-8084-exec-77) DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'mapLayerController'
    00:12:21,042 (http-bio-8084-exec-77) DEBUG [org.springframework.web.servlet.DispatcherServlet] - Last-Modified value for [/swtc/rest/map/getLayerData] is: -1
    00:12:44,844 (http-bio-8084-exec-77) DEBUG [org.springframework.web.servlet.DispatcherServlet] - Could not complete request
    javax.servlet.ServletException: Could not resolve view with name 'map/getLayerData' in servlet with name 'dispatcher'
        at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1190)
        at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:180)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:722)
    00:12:44,902 (http-bio-8084-exec-77) DEBUG [org.springframework.security.web.context.SecurityContextPersistenceFilter] - SecurityContextHolder now cleared, as request processing completed

1 个答案:

答案 0 :(得分:1)

尝试删除此行:

viewResolver.setViewNames(new String[] {"login", "index", "admin"});

这导致viewResolver忽略不在[“login”,“index”,“admin”]

中的所有内容

取自文件:

  

setViewNames

     

public void setViewNames(String [] viewNames)设置视图名称(或   名称模式)可以由此ViewResolver处理。查看名称   可以包含简单的通配符,例如'my *','* Report'和' Repo '   将全部匹配视图名称'myReport'。