VRaptor4 @Named Components in velocity 模板
VRaptor4 @Named Components in velocity template
我有一个 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
个组件?
看起来 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
}
}
当然,如果您只包含几个 bean,那么第一个解决方案就足够了。最好的问候
我有一个 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
个组件?
看起来 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
:
@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
}
}
当然,如果您只包含几个 bean,那么第一个解决方案就足够了。最好的问候