我有一个vraptor4项目,我想使用apache velocity
作为模板引擎。
所以我将br.com.caelum.vraptor.view.DefaultPathResolver
专门设为
@Specializes
public class VelocityPathResolver extends DefaultPathResolver {
@Inject
protected VelocityPathResolver(FormatResolver resolver) {
super(resolver);
}
protected String getPrefix() {
return "/WEB-INF/vm/";
}
protected String getExtension() {
return "vm";
}
}
工作正常,但我的模板中没有@Named
个组件。
有
@SessionScoped
@Named("mycmp")
public class MyComponent implements Serializable {
private static final long serialVersionUID = 1L;
private String name = "My Component";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
我不能在我的力度模板(.vm)中将其称为${mycmp.name}
,但如果我使用.jsp,它可以正常工作。
要解决这个问题,我将br.com.caelum.vraptor.core.DefaultResult
专门设为
@Specializes
public class VelocityResult extends DefaultResult {
private final MyComponent mycmp;
@Inject
public VelocityResult(HttpServletRequest request, Container container, ExceptionMapper exceptions, TypeNameExtractor extractor,
Messages messages, MyComponent mycmp) {
super(request, container, exceptions, extractor, messages);
this.mycmp = mycmp;
}
@PostConstruct
public void init() {
include("mycmp", mycmp);
}
}
在速度模板中使用@Named
组件有更好的方法吗?
答案 0 :(得分:1)
看起来CDI的@Named
不能使用力度模板,但您可以实施Interceptor
来完成这项工作。一个例子是:
@Intercepts
public class IncluderInterceptor {
@Inject private MyComponent mycmp;
@AfterCall public void after() {
result.include("mycmp", mycmp);
// any other bean you want to
}
}
在一个更灵活的解决方案中思考,您可以创建一个注释并使用它来定义应该包含哪个bean ......就像这样:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Included {
}
因此,您可以在课程中添加@Included
:
@Included public class MyComponent { ... }
只需在IncluderInterceptor
上添加accept方法:
@Intercepts
public class IncluderInterceptor {
@Inject @Any Instance<Object> allBeans;
@AfterCall public void after() {
// foreach allBeans, if has @Included, so
// include bean.getClass().getSimpleName()
// with first letter lower case, or something
}
}
当然,如果你只包含几个豆子,那么应该采用第一种解决方案。最好的问候