Thursday, August 4, 2016

spring-boot using multiple view resolvers from xml configuration not redirecting correctly

Leave a Comment

I have a legacy application using spring xml which I am migrating to spring-boot.

The application starts and I get the authentication page, mapped in the applicationContext-login.xml. On login successful it should load WEB-INF/client/home.jsp, but, instead, it tries to load /WEB-INF/auth/home.jsp and I get 404. In the startup log I see it mapping all the paths. Why is it conflicting on these redirects and what can I do to fix this? Does it encounter issues because of multiple @ImportResource containing view resolvers?

Extract from security http configuration:

    <s:http use-expressions="true" entry-point-ref="delegatingAuthenticationEntryPoint">         <s:form-login login-page="/auth/login"                       login-processing-url="/auth/j_spring_security_check"                       authentication-failure-url="/auth/login-secure?loginFailed=true"                       default-target-url="/auth/defaultEntry"/>         <s:logout logout-url="/auth/logout" logout-success-url="/auth/logout-success" delete-cookies="jsessionid"/>     </s:http> 

The controller it points to:

    @RequestMapping(value = "/defaultEntry", method = RequestMethod.GET)     public String defaultEntry() {         if (authentication.isAuthenticated()) {               return "redirect:/client/home";         } else {             return "redirect:login";         }     } 

The application has multiple view resolvers configured in xml files:

  • classpath*:/springContext/applicationContext-login.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:context="http://www.springframework.org/schema/context"     xmlns:mvc="http://www.springframework.org/schema/mvc"     xsi:schemaLocation="http://www.springframework.org/schema/beans                       http://www.springframework.org/schema/beans/spring-beans.xsd                       http://www.springframework.org/schema/context                       http://www.springframework.org/schema/context/spring-context.xsd                       http://www.springframework.org/schema/mvc                       http://www.springframework.org/schema/mvc/spring-mvc.xsd"     default-init-method="init"     default-destroy-method="destroy">    <import resource="applicationContext-web-common.xml" />    <!-- Static login resources -->   <mvc:resources mapping="/css/**" location="/WEB-INF/auth/css/"/>   <mvc:resources mapping="/assets/**" location="/WEB-INF/auth/assets/"/>   <mvc:resources mapping="/js/**" location="/WEB-INF/auth/js/"/>    <context:component-scan base-package="org.myCompany.auth" />    <!-- view resolver for JSP -->   <bean id="loginViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>       <property name="prefix" value="/WEB-INF/auth/"/>       <property name="suffix" value=".jsp"/>   </bean>    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">       <property name="defaultLocale" value="en_US"/>   </bean> 

  • classpath*:/springContext/applicationContext-client.xml"

    <?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"       xsi:schemaLocation="http://www.springframework.org/schema/beans                         http://www.springframework.org/schema/beans/spring-beans.xsd                         http://www.springframework.org/schema/context                         http://www.springframework.org/schema/context/spring-context.xsd                         http://www.springframework.org/schema/mvc                         http://www.springframework.org/schema/mvc/spring-mvc.xsd"       default-init-method="init"       default-destroy-method="destroy">      <import resource="applicationContext-web-common.xml" />      <context:component-scan base-package="org.myCompany.client" />      <!-- Static resources -->     <mvc:resources mapping="/player/**" location="/WEB-INF/client/player/"/>     <mvc:resources mapping="/css/**" location="/WEB-INF/client/css/"/>     <mvc:resources mapping="/data/**" location="/WEB-INF/client/data/"/>     <mvc:resources mapping="/js/**" location="/WEB-INF/client/js/"/>     <mvc:resources mapping="/locales/**" location="/WEB-INF/client/locales/"/>     <mvc:resources mapping="/media/**" location="/WEB-INF/client/media/"/>     <mvc:resources mapping="/index.html" location="/WEB-INF/client/index.html"/>     <mvc:resources mapping="/test.html" location="/WEB-INF/client/test.html"/>     <mvc:resources mapping="/admin/**" location="/WEB-INF/client/admin/"/>     <mvc:resources mapping="/documentation/**" location="/WEB-INF/client/documentation/"/>       <bean id="clientViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">         <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>         <property name="prefix" value="/WEB-INF/client/"/>         <property name="suffix" value=".jsp"/>     </bean>   </beans> 

There are also a few others following the same configuration pattern.

I am loading the resources in the Application.java

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})     //@EnableWebMvc     @ComponentScan({"org.myCompany"})     @ImportResource({"classpath*:/springContext/applicationContext-controllers.xml",             "classpath*:/springContext/applicationContext-rest.xml",             "classpath*:/springContext/applicationContext-login.xml",             "classpath*:/springContext/applicationContext-client.xml",             "classpath*:/springContext/applicationContext-admin.xml",             "classpath*:/springContext/applicationContext-logging.xml",             "classpath*:/springContext/applicationContext-web-common.xml"     })     public class Application extends SpringBootServletInitializer {          public static void main(String[] args) throws UnknownHostException {             SpringApplication app = new SpringApplication(Application.class);             ApplicationContext ctx = app.run(args);             Environment env = ctx.getEnvironment();              logger.info(String.format("\n----------------------------------------------------------\n\t" +                             "Application '%s' is running! Access URLs:\n\t" +                             "Local: \t\thttp://localhost:%s\n\t" +                             "External: \thttp://%s:%s\n----------------------------------------------------------",                     env.getProperty("spring.application.name"),                     env.getProperty("server.port"),                     InetAddress.getLocalHost().getHostAddress(),                     env.getProperty("server.port")));         }          @Bean         public ServletRegistrationBean restDispatcher() {             ServletRegistrationBean registration = new ServletRegistrationBean(new DispatcherServlet(),                     "/rest/*", "/websocket/*");             registration.setName("rest-dispatcher");             registration.setLoadOnStartup(2);             Map<String, String> params = new HashMap<>();             params.put("contextConfigLocation", "classpath*:springContext/applicationContext-rest.xml");             registration.setInitParameters(params);             return registration;         }          @Bean         public ServletRegistrationBean authDispatcher() {             ServletRegistrationBean registration = new ServletRegistrationBean(new DispatcherServlet(), "/auth/*");             registration.setName("auth-dispatcher");             registration.setLoadOnStartup(2);             Map<String, String> params = new HashMap<>();             params.put("contextConfigLocation", "classpath*:springContext/applicationContext-login.xml");             registration.setInitParameters(params);             return registration;         }          @Bean         public ServletRegistrationBean clientDispatcher() {             ServletRegistrationBean registration = new ServletRegistrationBean(new DispatcherServlet(), "/client/*");             registration.setName("client-dispatcher");             registration.setLoadOnStartup(2);             Map<String, String> params = new HashMap<>();             params.put("contextConfigLocation", "classpath*:springContext/applicationContext-client.xml");             registration.setInitParameters(params);             return registration;         }      //... other servlets registration, filters registration      } 

3 Answers

Answers 1

You are returning redirect:/client/home from your login screen which will get processed by your loginViewResolver:

<bean id="loginViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>       <property name="prefix" value="/WEB-INF/auth/"/>       <property name="suffix" value=".jsp"/>   </bean> 

The clientViewResolver does not get invoked since there is no order specified on the view resolvers. You can set the order using the order property.,

Answers 2

I may assume, that this is caused by Spring Security configuration, and does not depend from View Resolvers. It looks like after success login user is being redirected to page, which he tried to access before, and it may not be /defaultEntry. Try edit your Spring Security http configuration as follows:

<s:http use-expressions="true" entry-point-aref="delegatingAuthenticationEntryPoint">     <s:form-login login-page="/auth/login"                   login-processing-url="/auth/j_spring_security_check"                   authentication-failure-url="/auth/login-secure?loginFailed=true"                   default-target-url="/auth/defaultEntry"                   always-use-default-target="true"/>     <s:logout logout-url="/auth/logout" logout-success-url="/auth/logout-success" delete-cookies="jsessionid"/> </s:http> 

If it helps - you'll get a clue where to look further.

Also, check it out this StackOverFlow answer.

Answers 3

The problem with your dispatcher servlet configuration you defined

  <bean id="clientViewResolve" class="org.springframework.web.servlet.view.InternalResourceViewResolver">   <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>   <property name="prefix" value="/WEB-INF/client/"/>   <property name="suffix" value=".jsp"/> 

With that configuration , its likely to get resolved to /WEB-INF/client/client/*.jsp

Its better to use a single viewresolver rather than complexing the task of having two view resolvers.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment