2015-06-22 132 views
0

我想在我的web应用中使用Thymeleaf作为模板引擎。我在Google上搜索到用struts2配置Themeleaf,发现一些解决方案有一个plugin。我在我的应用程序中配置了插件,但我无法使用插件呈现页面。而是我得到错误:Struts 2 with Thymeleaf

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/WEB-INF/templates/hello.html", template might not exist or might not be accessible by any of the configured Template Resolvers 
    org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:246) 
    org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104) 
    org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060) 
    org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011) 
    org.thymeleaf.TemplateEngine.process(TemplateEngine.java:955) 
    com.struts.custom.resulttype.plugin.ThemeleafResult.execute(ThemeleafResult.java:51) 
    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:374) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:278) 
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265) 
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:211) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:211) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:90) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:192) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) 
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:510) 
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) 
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91) 

这是落实DefaultTemplateEngineProvider.java

public class DefaultTemplateEngineProvider implements TemplateEngineProvider { 
    // HTML5 is the future! 
    private String templateMode = "HTML5"; 
    private String characterEncoding = "UTF-8"; 
    // This will convert "home" to "/WEB-INF/templates/home.html" 
    private String prefix = "/WEB-INF/templates/"; 
    private String suffix = ".html"; 
    private boolean cacheable = true; 

    // Default template cache TTL to 1 hour. If not set, entries would live in 
    // cache until expelled by LRU. 
    private Long cacheTtlMillis = 3600000L; 

    private TemplateEngine templateEngine; 

    /** 
    * Configure settings from the struts.xml or struts.properties, using sensible 
    * defaults if values are not provided. 
    */ 
    public void configure() { 
    ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(); 
    templateResolver.setTemplateMode(templateMode); 
    templateResolver.setCharacterEncoding(characterEncoding); 
    templateResolver.setPrefix(prefix); 
    templateResolver.setSuffix(suffix); 
    templateResolver.setCacheable(cacheable); 
    templateResolver.setCacheTTLMs(cacheTtlMillis); 

    templateEngine = new TemplateEngine(); 
    templateEngine.setTemplateResolver(templateResolver); 
    templateEngine.setMessageResolver(new StrutsMessageResolver()); 
    } 


    public TemplateEngine get() { 
    if (templateEngine == null) { 
     configure(); 
    } 

    return templateEngine; 
    } 

    @Inject(value = "struts.thymeleaf.templateMode", required = false) 
    public void setTemplateMode(String templateMode) { 
    this.templateMode = templateMode; 
    } 

    @Inject(value = "struts.thymeleaf.encoding", required = false) 
    public void setCharacterEncoding(String characterEncoding) { 
    this.characterEncoding = characterEncoding; 
    } 

    @Inject(value = "struts.thymeleaf.prefix", required = false) 
    public void setPrefix(String prefix) { 
    this.prefix = prefix; 
    } 

    @Inject(value = "struts.thymeleaf.suffix", required = false) 
    public void setSuffix(String suffix) { 
    this.suffix = suffix; 
    } 

    @Inject(value = "struts.thymeleaf.cacheable", required = false) 
    public void setCacheable(String cacheable) { 
    this.cacheable = Boolean.parseBoolean(cacheable); 
    } 

    @Inject(value = "struts.thymeleaf.cacheTtlMillis", required = false) 
    public void setCacheTtlMillis(String cacheTtlMillis) { 
    this.cacheTtlMillis = Long.parseLong(cacheTtlMillis); 
    } 
} 

我已经写了自定义的结果集,并在官方网站的文件配置Thymeleaf。但得到同样的错误。

我的自定义结果类型为

public class ThymeleafResult implements Result { 
    private String defaultEncoding = "UTF-8"; 
    private TemplateEngineProvider templateEngineProvider; 
    private String templateName; 

    /** 
    * The result parameter name to set the name of the template to. 
    * <p/> 
    * IMPORTANT! Struts2 will look for this field reflectively to determine which 
    * parameter is the default. This allows us to have a simplified result 
    * configuration. Don't remove it! 
    */ 
    public static final String DEFAULT_PARAM = "templateName"; 

    public ThymeleafResult() { 
    } 

    public ThymeleafResult(String templateName) { 
    this.templateName = templateName; 
    } 


    public void execute(ActionInvocation actionInvocation) throws Exception { 
    TemplateEngine templateEngine = templateEngineProvider.get(); 

    HttpServletRequest request = ServletActionContext.getRequest(); 
    HttpServletResponse response = ServletActionContext.getResponse(); 
    ServletContext servletContext = ServletActionContext.getServletContext(); 

    Object action = actionInvocation.getAction(); 

    StrutsContext context = new StrutsContext(request, response, servletContext, action); 
    response.setContentType("text/html"); 
    response.setCharacterEncoding(defaultEncoding); 
    System.out.println(templateName); 
    templateEngine.process(templateName, context, response.getWriter()); 
    } 

    @Inject(StrutsConstants.STRUTS_I18N_ENCODING) 
    public void setDefaultEncoding(String defaultEncoding) { 
    this.defaultEncoding = defaultEncoding; 
    } 

    @Inject 
    public void setTemplateEngineProvider(TemplateEngineProvider templateEngineProvider) { 
    this.templateEngineProvider = templateEngineProvider; 
    } 

    public void setTemplateName(String templateName) { 
    this.templateName = templateName; 
    } 

而且struts.xml的是

<struts> 

    <constant name="struts.enable.DynamicMethodInvocation" value="false" /> 
    <constant name="struts.devMode" value="true" /> 
    <constant name="struts.multipart.maxSize" value="1000000000" /> 
    <constant name="struts.custom.i18n.resources" value="ApplicationResources" /> 
    <bean type="org.codework.struts.plugins.thymeleaf.spi.TemplateEngineProvider" name="default" class="org.codework.struts.plugins.thymeleaf.spi.DefaultTemplateEngineProvider" /> 

    <package name="default" namespace="/" extends="struts-default"> 
     <result-types> 
      <result-type name="thymeleaf" class="org.codework.struts.plugins.thymeleaf.ThymeleafResult"/> 
     </result-types> 
     <default-action-ref name="home"></default-action-ref> 
     <action name="home" class="com.demo.example.Welcome"> 
      <result name="success" type="thymeleaf">/WEB-INF/templates/hello.html</result> 
     </action> 
    </package> 
</struts> 
+0

你能告诉我们你的代码以及你如何配置它来运行,而不仅仅是错误吗? (更多,因为我懒得阅读文档比其他任何东西) –

+0

检查模板文件的位置,Struts把他们的模板放在资源下。 –

+0

@ShotgunNinja我已添加更多详情。请检查我做错了什么。 –

回答

2

我已经找到了解决办法:我是做struts.xml中一个错误的映射。

我刚刚更换

<result name="success" type="thymeleaf">/WEB-INF/templates/hello.html</result> 

<result name="success" type="thymeleaf">hello</result> 

和它的工作。