使用Apache Tiles进行Spring Boot

时间:2014-04-05 18:56:51

标签: spring apache tiles spring-boot apache-tiles

我正在尝试将我的java应用程序迁移到Spring Boot。目前,我正在使用Apache Tiles运行Spring MVC 3.2。当我迁移到Spring Boot时,我的控制器仍被调用,他们将视图传递给视图Resolver,但是当Tiles去拉JSP文件时,事情就会崩溃。我得到的错误信息是:

13:48:46,387 TRACE org.springframework.web.servlet.handler.SimpleUrlHandlerMapping:127 - No handler mapping found for [/jsp/layout/layout.jsp]

有没有人成功使用过Spring Boot的Apache Tiles?任何想法怎么做?

提前感谢任何想法!


更多详情:

@Bean
    public UrlBasedViewResolver viewResolver(){
        LOGGER.trace("Entering tiles configurer");
        UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
        viewResolver.setViewClass(TilesView.class);
        return viewResolver;
    }
    @Bean
    public TilesConfigurer tilesConfigurer(){
        LOGGER.trace("Entering tiles configurer");
        System.out.println("Entering tiles configurer");
        TilesConfigurer tilesConfigurer = new TilesConfigurer();
        String[] defs = {"/WEB-INF/tiles-defs.xml"};
        tilesConfigurer.setDefinitions(defs);
        return tilesConfigurer;
    }

控制器:

        @RequestMapping(value="/")
        public ModelAndView index(ModelAndView mav, HttpServletRequest request, HttpServletResponse resp,RedirectAttributes ra){
            LOGGER.trace("Arrived in Home Controller");
            mav.addObject("profile",appContext.getEnvironment().getActiveProfiles()[0]);
            mav.setViewName("home");
            return mav;
        }

tiles-definitions:

        <definition name="layout" template = "/jsp/layout/layout.jsp">
        </definition>
        <definition name="home" extends="layout">
            <put-attribute name="body" value = "/jsp/home.jsp" />
        </definition>

5 个答案:

答案 0 :(得分:5)

我也遇到了类似的问题,并且能够在上面的各种答案的帮助下解决它。为了帮助将来可能遇到此问题的其他人,我在https://github.com/barryku/spring-boot-tiles创建了一个简单的Maven项目,以包含使用Spring Boot启用磁贴所需的最低设置。以下是一些需要注意的事项,

  1. 渲染JSP页面需要tomcat-embed-jasper
  2. 记得使用org.springframework.web.servlet.view.tiles3而不是tiles2包
  3. jstl由Spring的tiles3集成使用,因此必须包含
  4. 我逐步添加了所需文件,因此您可以查看https://github.com/barryku/spring-boot-tiles/commits/master处的提交历史记录,以便更好地了解每个步骤中添加的内容。

答案 1 :(得分:4)

我在/src/main/webapp/WEB-INF/layouts/layouts.xml中有我的主要布局,其示例条目如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">

<tiles-definitions>

  <definition name="default" template="/WEB-INF/layouts/default.jspx">

    <put-attribute name="menu" value="/WEB-INF/views/menu.jspx"/>
    <put-attribute name="sidebar" value="/WEB-INF/views/sidebar.jspx"/>    
    <put-attribute name="header" value="/WEB-INF/views/header.jspx" />
    <put-attribute name="footer" value="/WEB-INF/views/footer.jspx" />
  </definition>

  <definition name="public" template="/WEB-INF/layouts/default.jspx"> 

    <put-attribute name="menu" value="/WEB-INF/views/menu.jspx"/>
    <put-attribute name="sidebar" value="/WEB-INF/views/sidebar.jspx"/> 
    <put-attribute name="header" value="/WEB-INF/views/header.jspx" />
    <put-attribute name="footer" value="/WEB-INF/views/footer.jspx" />
  </definition>

</tiles-definitions>

然后/src/main/webapp/WEB-INF/views/views.xml中更具体的切片定义,其中包含以下示例条目:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>

  <definition extends="default" name="index"> 
    <put-attribute name="body" value="/WEB-INF/views/index.jspx"/>
  </definition>

  <definition extends="public" name="login">
        <put-attribute name="sidebar" value=""></put-attribute>
        <put-attribute name="body" value="/WEB-INF/views/login.jspx"/>
    </definition>
</tiles-definitions>

然后你需要你的配置类:

@EnableWebMvc
@Configuration
public class RootMvcConfiguration extends WebMvcConfigurerAdapter {
    ...
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

      registry.addViewController("/").setViewName("index");
      registry.addViewController("/login").setViewName("login");
    }
    ...
}

该类中与tile相关的Bean依赖 - 如果您想使用JSP或Thymeleaf。

对于JSP,你应该有:

 @Bean 
 public UrlBasedViewResolver tilesViewResolver(){

    UrlBasedViewResolver tilesViewResolver = new UrlBasedViewResolver();
    tilesViewResolver.setViewClass(TilesView.class);
    return tilesViewResolver;
}
 @Bean
 public TilesConfigurer tilesConfigurer(){ 

    String[] definitions = new String[] {
            "/WEB-INF/layouts/layouts.xml",
            "/WEB-INF/views/**/views.xml" /*Scans directories for Tiles configurations */
            };

    TilesConfigurer tilesConfigurer = new TilesConfigurer();
    tilesConfigurer.setDefinitions(definitions);
    return tilesConfigurer;

 }

如果你使用Thymeleaf,你应该有类似的东西:

@Bean
public MessageSource messageSource(){

    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasenames("classpath:META-INF/i18n/messages");
    messageSource.setFallbackToSystemLocale(false);
    return messageSource;
}
@Bean 
public ServletContextTemplateResolver templateResolver() {
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setPrefix("/WEB-INF/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode("HTML5");
        resolver.setOrder(2);
        resolver.setCacheable(false);            
        return resolver;
}

@Bean 
public SpringTemplateEngine templateEngine() throws Exception {
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(templateResolver());
        engine.setTemplateEngineMessageSource(messageSource());
        engine.addDialect(new TilesDialect());            
        engine.addDialect(new SpringSecurityDialect());            
        engine.afterPropertiesSet();
        return engine;
}
@Bean
public TilesConfigurer tilesConfigurer(){ 

    String[] definitions = new String[] {
            "/WEB-INF/layouts/layouts.xml",
            "/WEB-INF/views/**/views.xml" /*Scans directories for Tiles configurations */
            };

    ThymeleafTilesConfigurer tilesConfigurer = new ThymeleafTilesConfigurer();
    tilesConfigurer.setDefinitions(definitions);        
    return tilesConfigurer;

}

然后,您可以将views.xml和点视图名称扩展为jsp或html文件,示例控制器可以如下所示:

@RequestMapping("/roles")
@Controller
public class RoleController {

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String show(@PathVariable("id") Integer id, Model uiModel) {
        uiModel.addAttribute("role", Role.findRole(id));
        uiModel.addAttribute("itemId", id);
        return "roles/show";
    }
}

如果你使用Maven,这里有一些示例lib版本:

<properties>        
    <thymeleaf.version>2.0.19</thymeleaf.version>
    <thymeleaf.extras.version>2.0.0</thymeleaf.extras.version>         
    <thymeleaf.extras.security.version>2.0.0</thymeleaf.extras.security.version>
    <tiles.version>2.2.2</tiles.version>
</properties>
...
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>${jstl.version}</version>
    </dependency>

            <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-core</artifactId>
        <version>${tiles.version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-jsp</artifactId>
        <version>${tiles.version}</version>
    </dependency>  

    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf</artifactId>
        <version>${thymeleaf.version}</version>
    </dependency>

    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring3</artifactId>
        <version>${thymeleaf.version}</version>
    </dependency>

    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity3</artifactId>
        <version>${thymeleaf.extras.security.version}</version>
    </dependency>

    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-tiles2</artifactId>
        <version>${thymeleaf.extras.version}</version>
    </dependency>

答案 2 :(得分:1)

您必须将自己的应用打包为战争。 Spring-boot,jsp和jar包装不能相处得很好。 还要确保在pom.xml中包含以下内容:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>

答案 3 :(得分:0)

您的定义应该是:

    <definition name="layout" template = "/WEB-INF/jsp/layout/layout.jsp">
    </definition>
    <definition name="home" extends="layout">
        <put-attribute name="body" value = "/WEB-INF/jsp/home.jsp" />
    </definition>

答案 4 :(得分:0)

我在this question中遇到了同样的问题。问题是路径和前缀。在Tiles定义中,我有像/WEB-INF/views/test.html这样的路径,这是一个错误。下面我将为Spring应用程序(Thymeleaf 2,Tiles 2)和示例文件提供完整的工作配置。也许它会帮助别人。

<强>豆

@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/test").setViewName("tiles/test");
    }

    @Bean
    public ServletContextTemplateResolver servletContextTemplateResolver() {
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode("HTML5");
        resolver.setCharacterEncoding("UTF-8");     
        return resolver;
    }   

    /**
     * Tiles view resolver
     * @param templateEngine
     * @return
     */
    @Bean
    public ViewResolver vr(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver th = new ThymeleafViewResolver();
        th.setTemplateEngine(templateEngine);
        th.setViewClass(ThymeleafTilesView.class);
        th.setCharacterEncoding("UTF-8");
        th.setOrder(Ordered.LOWEST_PRECEDENCE);
        return th;
    }

    /**
     * Basic view resolver
     * @param templateEngine
     * @return
     */
    @Bean
    public ViewResolver thymeleafViewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver vr = new ThymeleafViewResolver();
        vr.setTemplateEngine(templateEngine);
        vr.setCharacterEncoding("UTF-8");
        vr.setOrder(Ordered.HIGHEST_PRECEDENCE);
        // all tiles/* views will not be handled by this resolver;
        vr.setExcludedViewNames(new String[]{"tiles/*"});
        return vr;
    }   

    @Bean
    public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        log.info(templateResolver);
        templateEngine.addDialect(new SpringSecurityDialect());
        templateEngine.addDialect(new TilesDialect());
        return templateEngine;
    }

    @Bean
    @SuppressWarnings("deprecation")
    public ThymeleafTilesConfigurer tilesConfigurer() {
        ThymeleafTilesConfigurer ttc = new ThymeleafTilesConfigurer();
        ttc.setDefinitions(new String[]{"/WEB-INF/tiles.xml"});
        return ttc;
    }   
}

磁贴定义 - src / main / webapp / WEB-INF / tiles.xml

模板路径相对于templateResolver 前缀且没有后缀。当我使用完整路径时,它不起作用并且像

一样出现异常
  

解析模板时遇到错误&#34; /WEB-INF/views/layout.html" ;,模板可能   任何已配置的模板都不存在或可能无法访问   解析器

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
          "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
          "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>

  <definition name="baseLayout" template="layout">
  </definition>

  <definition name="tiles/test" extends="baseLayout">
    <put-attribute name="body" value="test"/>
    <put-attribute name="title" value="Test Page"/>
  </definition>
</tiles-definitions>

<强>的src /主/ web应用/ WEB-INF /视图/的layout.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://tiles.apache.org/tags-tiles">
<head>
    <title tiles:string="title">blah blah blah</title>
    <style type="text/css"></style>
</head>
<body>
    <div class="container">
        <div tiles:replace="body"></div>
    </div>
</body>
</html>

<强>的src /主/ web应用/ WEB-INF /视图/的test.html

2+2=<span xmlns:th="http://www.thymeleaf.org" th:text="2+2"></span>