Mixing thymeleaf and jsp files in Spring Boot

2019-09-07 06:05发布

问题:

Is there anyway to use plain jsp files without a controller mixed with thymeleaf views using controllers in Spring Boot/MVC?

For example, a standard controller is as follows;

@RequestMapping("/")
public String get() {
    return "view";
}

Which works exactly as expected, but is it possible to map ".jsp" files put in a folder to any url for example test.jsp would go to www.website.com/test.jsp

Regards.

回答1:

I use the following configuration in servlet-context.xml (the contextConfigLocation of the DispatcherServlet):

<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
    in the /WEB-INF/views directory -->
<beans:bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
    <beans:property name="viewNames" value="jsp/*"></beans:property>
    <beans:property name="order" value="1"></beans:property>
</beans:bean>

<!-- Thymeleaf -->
<beans:bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <beans:property name="templateEngine" ref="templateEngine" />
    <!-- This narrows the scope of the resolver to the view names (returned 
        by the controllers' methods) to those matching the pattern -->
    <beans:property name="viewNames" value="templates/*"></beans:property>
    <!-- places this resolver before the default InternalResourceViewResolver -->
    <beans:property name="order" value="0"></beans:property>
</beans:bean>

<beans:bean id="templateResolver"
    class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="templateMode" value="HTML5" />
    <beans:property name="suffix" value=".html" />
</beans:bean>

<beans:bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
    <beans:property name="templateResolver" ref="templateResolver" />
</beans:bean>

<!-- Thymeleaf _ end -->

In order to render the response with a JSP, in the controller I return a string like the following:

@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {

    return "jsp/home";
}

whereas to render with a thymeleaf template, I do the following:

@RequestMapping(value = "/", method = RequestMethod.GET)
public String getRanks(Model model, HttpServletRequest request)
{
    return "templates/user/ranks";
}

Of course, the physical location of the .jsp and .html files must match the view name returned by the controllers. So, according to how the resolvers are configured, you will have to place .jsp files inside /views/jsp and .html files (for thymeleaf) inside /views/templates

If you want a url like www.website.com/test.jsp to be rendered with the test.jsp view, you can simply put the aformentiond jsp file inside the root directory of your webapp. The request should be resolved by the JSP servlet, if no strange configuration is in place. In fact, a servlet container like Tomcat normally have this specification in its global web.xml file:

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>

and

<!-- The mappings for the JSP servlet -->
<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>

If you want something more customized and specific, you will have to modify your configuration accordingly. For example, remove the JSP servlet from you servlet container's web.xml and map *.jsp url in the appropriate controllers