Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Freemarker URLTemplate loader将国际化添加到模板名称,并且多个加载程序不工作_Java_Spring_Spring Mvc_Freemarker - Fatal编程技术网

Java Freemarker URLTemplate loader将国际化添加到模板名称,并且多个加载程序不工作

Java Freemarker URLTemplate loader将国际化添加到模板名称,并且多个加载程序不工作,java,spring,spring-mvc,freemarker,Java,Spring,Spring Mvc,Freemarker,我有一个SpringMVC应用程序,我正在尝试使用freemarker作为视图解析器。我正在尝试设置它,以便它首先检查不同的服务器,然后在本地检查。以下是相关代码: <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="templateLoaderPath" value="/WEB-IN

我有一个SpringMVC应用程序,我正在尝试使用freemarker作为视图解析器。我正在尝试设置它,以便它首先检查不同的服务器,然后在本地检查。以下是相关代码:

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  <property name="templateLoaderPath" value="/WEB-INF/ftl/"/>
  <property name="preTemplateLoaders" ref="myTemplateLoader"/>
</bean>

<bean  class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="cache" value="true"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".ftl"/>
        <property name="order" value="2" />
    </bean>

    <bean id="myTemplateLoader" class="com.xxx.MyURLTemplateLoader">
        <property name="baseUrl" value="http://10.0.0.5:8080/ftl/"/>
    </bean>
}

控制器很简单:

ModelAndView view = new ModelAndView("index2");
return view;
现在当我运行这个时,我得到一个404错误。奇怪的是,我在日志中看到了这一点:

URL Being used:http://10.0.0.5:8080/ftl/index2_en_US.ftl
那么,为什么要把它添加到我的URL中呢


另外,如果我删除了预模板加载程序,它工作得很好,它可以很好地拾取本地模板。但是添加URLTemplateLoader,不仅会将_en_US添加到模板名称中,而且在本地也找不到它

FreeMarker有一些不吉利的传统配置默认值,其中之一是本地化的查找默认为true。这就是为什么它首先试图找到index2_en_US.ftl,然后如果缺少index2_en.ftl,最后是index2.ftl。另外,您使用的TemplateLoader实现显然有一个不正确的findTemplateSource方法,因此上述回退机制不起作用。因此,findTemplateSource应该是固定的,并且您希望关闭本地化查找:

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  ...
  <property name="freemarkerSettings">
    <props>
      <prop key="localized_lookup">false</prop>
      <!-- Some unrelated but useful default overrides: -->
      <prop key="incompatible_improvements">2.3.23</prop>
      <prop key="template_exception_handler">rethrow</prop>
      <prop key="log_template_exceptions">false</prop>
      <prop key="default_encoding">UTF-8</prop>
    </props>
  </property>
</bean>

多亏了ddekany解决了本地化问题。那就把它修好了

然而,第二个问题要困难得多

事实证明,有一个未记录的特性,如果你设置了一个模板加载器,它会清除默认的加载器org.springframework.ui.freemarker.SpringTemplateLoader,因此如果你想要2个或更多的加载器,你需要自己的加载器。不幸的是,SpringTemplateLoader将ServletContext作为构造参数,您无法在context.xml文件中轻松定义它

所以我所做的是重新编写SpringTemplateLoader,使其具有ServletContext意识。这是我的密码:

public class MyWebappTemplateLoader implements TemplateLoader, ServletContextAware  {

static final Logger logger = LoggerFactory.getLogger(MyWebappTemplateLoader.class);
private ResourceLoader resourceLoader = null;
private String templateLoaderPath = null;
private ServletContext servletContext;

private void init() {
    GenericWebApplicationContext context = new  GenericWebApplicationContext(servletContext);
    resourceLoader = (ResourceLoader)context;
    if (logger.isInfoEnabled()) {
        logger.info("SpringTemplateLoader for FreeMarker: using resource loader [" + this.resourceLoader +
                "] and template loader path [" + this.templateLoaderPath + "]");
    }       
}

public Object findTemplateSource(String name) throws IOException {
    if (logger.isDebugEnabled()) {
        logger.debug("Looking for FreeMarker template with name [" + name + "]");
    }
    if(this.resourceLoader==null) {
        init();
    }
    Resource resource = this.resourceLoader.getResource(this.templateLoaderPath + name);
    return (resource.exists() ? resource : null);
}


public Reader getReader(Object templateSource, String encoding) throws IOException {
    Resource resource = (Resource) templateSource;
    try {
        return new InputStreamReader(resource.getInputStream(), encoding);
    }
    catch (IOException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Could not find FreeMarker template: " + resource);
        }
        throw ex;
    }
}

public long getLastModified(Object templateSource) {
    return -1;
}

public void closeTemplateSource(Object templateSource) throws IOException {
}

public void setTemplateLoaderPath(String arg0) {
    if (!arg0.endsWith("/")) {
        arg0 += "/";
    }
    this.templateLoaderPath = arg0;
}

@Override
public void setServletContext(ServletContext arg0) {
    this.servletContext = arg0;

}
} 
我的xml现在看起来像这样:

public class MyURLTemplateLoader extends URLTemplateLoader  {

private String baseUrl;

@Override
protected URL getURL(String arg0){
    URL url = null;
    try {
        url = new URL(baseUrl+arg0);
        System.out.println("URL Being used:"+url.toString());
    } catch (Exception s) {
        s.printStackTrace();
    }
    return url;
}

public String getBaseUrl() {
    return baseUrl;
}

public void setBaseUrl(String baseUrl) {
    this.baseUrl = baseUrl;
}
        <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="preTemplateLoaders" ref="multiTemplateLoader"/>  
        <property name="freemarkerSettings">
            <props>
                <prop key="default_encoding">UTF-8</prop>
                <prop key="localized_lookup">false</prop>
            </props>
        </property>  
    </bean>


    <bean id="fremarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="cache" value="true"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".ftl"/>
        <property name="order" value="2" />
    </bean>

    <bean id="myUrlTemplateLoader" class="com.xxx.MyURLTemplateLoader">
        <property name="baseUrl" value="http://10.0.0.5:8080/ftl/"/>
    </bean>

    <bean id="defaultTemplateLoader" class="com.xxx.MyWebappTemplateLoader">
        <property name="templateLoaderPath" value="/WEB-INF/ftl/" /> 
    </bean>

    <bean id="multiTemplateLoader" class="freemarker.cache.MultiTemplateLoader">
        <constructor-arg>
          <list>
            <ref bean="myUrlTemplateLoader"/>
            <ref bean="defaultTemplateLoader"/> 
          </list>
        </constructor-arg>
    </bean>
如果有人知道更好的方法,我很想看看

        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        if(conn.getResponseCode()!=200) {
            return null;
        }