更改 Mustache 的编译器默认 null 值

问题描述 投票:0回答:3

我在覆盖我的项目中here发现的 Spring MVC Mustache 默认配置时遇到了一些问题。

我的理解是,当模板发现一个解析为 null 的变量时,mustache.java 默认会引发

MustacheException
。我希望 Mustache 编译器将这些值解析为空字符串。

我尝试使用

nullValue(String nullValue)
函数来设置适当的行为,如下面的代码所示,但它似乎没有任何效果。我知道明显的解决方案是将
phoneNumber
属性设置为空值,但我真的很想了解为什么这个特定的代码不起作用。

您将在下面找到我用来测试此行为的代码,其中包括一个

Employee
实体,该实体故意不在其构造函数和相关代码片段中实例化其
phoneNumber
成员值。

pom.xml

<dependency>
  <groupId>com.github.sps.mustache</groupId>
  <artifactId>mustache-spring-view</artifactId>
  <version>1.3</version>
</dependency>
<!-- jmustache -->
<dependency>
  <groupId>com.samskivert</groupId>
  <artifactId>jmustache</artifactId>
  <version>1.10</version>
</dependency>
<!-- mustache.java -->
<dependency>
  <groupId>com.github.spullara.mustache.java</groupId>
  <artifactId>compiler</artifactId>
  <version>0.8.17</version>
</dependency>

Employee.java

public class Employee {

  protected String firstName;
  protected String lastName;
  protected String phoneNumber;

  public Employee() { }
  public Employee(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  // Getter and Setters for all attributes
}

获取ViewResolver

@Bean
public ViewResolver getViewResolver(ResourceLoader resourceLoader) {
  MustacheViewResolver mustacheViewResolver = new MustacheViewResolver();
  mustacheViewResolver.setPrefix("/src/main/resources/templates/");
  mustacheViewResolver.setSuffix(".html");
  mustacheViewResolver.setCache(false);
  mustacheViewResolver.setContentType("text/html;charset=utf-8");

  JMustacheTemplateLoader mustacheTemplateLoader = new JMustacheTemplateLoader();
  mustacheTemplateLoader.setResourceLoader(resourceLoader);

  JMustacheTemplateFactory mustacheTemplateFactory = new JMustacheTemplateFactory();
  mustacheTemplateFactory.setTemplateLoader(mustacheTemplateLoader);

  mustacheTemplateFactory.setCompiler(Mustache.compiler().nullValue(" "));

  mustacheViewResolver.setTemplateFactory(mustacheTemplateFactory);
  return mustacheViewResolver;
}

员工控制器

@Autowired
private EmployeeRepository repository;

...

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String viewEmployee(@PathVariable Long id, Model model) {
  model.addAttribute("employee", repository.findOne(id));
  return "employee_view";
}

employee_view.html

<!DOCTYPE html>
<html>
  <body>
  <ul>
    {{#employee}}
    <li> First Name: {{firstName}}
    <li> Last Name: {{lastName}}
    <li> Phone Number: {{phoneNumber}}
    {{/employee}}
  </ul>
  </body>
</html>
spring spring-mvc mustache
3个回答
1
投票

我现在使用的是spring-boot.1.2.5.RELEASE。

如果你查看

org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration
的源代码(第73~78行),你会发现
defaultValue
是不可配置的。

也许你应该制作一个新的你自己的 Spring Boot 启动器来修复它。 或者您可以使用 FreeMarker 或 Velocity 代替它。

或者您可以在 ApplicationContext 启动时使用

BeanPostProcessor
破解它。

像这样:

@Bean
public BeanPostProcessor mutacheHackerBeanPostProcessor() {
    return new BeanPostProcessor() {
        private static final String BEAN_NAME = "mustacheCompiler";

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (ClassUtils.isAssignable(bean.getClass(), Mustache.Compiler.class) || BEAN_NAME.equals(beanName)) {
                System.out.println("----------");
                System.out.println("hack ok!!!");
                System.out.println("----------");
                Mustache.Compiler compiler = (Mustache.Compiler) bean;
                return compiler.defaultValue("").nullValue("");
            }

            return bean;
        }
    };
}

1
投票

我设法通过创建自定义 Mustache 自动配置来做到这一点。首先排除默认的 MustacheAutoConfiguration。

@SpringBootApplication
@EnableAutoConfiguration(exclude = MustacheAutoConfiguration.class)
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

然后为 Mustache 创建新的自动配置。

@Configuration
@EnableConfigurationProperties({MustacheProperties.class})
public class LayoutAutoConfiguration extends MustacheAutoConfiguration {

    public LayoutAutoConfiguration(MustacheProperties mustache, Environment environment, ApplicationContext applicationContext) {
        super(mustache, environment, applicationContext);
    }

    @Override
    public Mustache.Compiler mustacheCompiler(Mustache.TemplateLoader mustacheTemplateLoader) {
        return super.mustacheCompiler(mustacheTemplateLoader).defaultValue("");
    }
}

Spring Boot 1.5.1.RELEASE 与 jmustache 1.13。


0
投票

你尝试过这个吗?

<!DOCTYPE html>
<html>
<body>
<ul>
{{#employee}}
  <li> First Name: {{firstName}}
  <li> Last Name: {{lastName}}
  <li> Phone Number:{{#phoneNumber}} {{phoneNumber}} {{/phoneNumber}}     {{^phoneNumber}} NA {{/phoneNumber}}
{{/employee}}
</ul>
</body>

© www.soinside.com 2019 - 2024. All rights reserved.