2015-01-19 4 views
1

나는 vraptor4 프로젝트를 가지고 있으며 apache velocity을 템플릿 엔진으로 사용하려고합니다. VRaptor4 @Named 속도 템플릿의 구성 요소

그래서 나는 전문 br.com.caelum.vraptor.view.DefaultPathResolver 잘 작동,하지만 난 내 템플릿 @Named 구성 요소를 가질 수 없습니다
@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"; 
    } 
} 

있다.

@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 구성 요소를 가지고위한 더 나은 방법이 있습니까?

답변

1

CDI의 @Named은 속도 템플릿과 호환되지 않지만이 작업을 수행하려면 Interceptor을 구현할 수 있습니다. 예제는 다음과 같습니다 그래서

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface Included { 
} 

:

@Intercepts 
public class IncluderInterceptor { 

    @Inject private MyComponent mycmp; 

    @AfterCall public void after() { 
     result.include("mycmp", mycmp); 
     // any other bean you want to 
    } 
} 

그리고 더 유연한 솔루션의 생각, 당신은 ... 그런 것을 주석을 만들고 포함되어야하는 빈 정의하는 데 사용할 수 있습니다

@Included public class MyComponent { ... } 

을 그냥 IncluderInterceptor에 동의 방법을 추가 : 당신은 당신의 클래스에 @Included을 추가 할 수

@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 
    } 
} 

물론 약간의 콩만 포함한다면 첫 번째 해결책은 충분할 것입니다. 안부 인사

+0

첫 번째 솔루션으로 결과에 MyComponent를 추가 할 수 있습니다. 하지만 두 번째 솔루션이 어떻게 작동하는지 알지 못합니다. 두 번째 솔루션으로 MyComponent가 아닌 결과에 컨트롤러를 추가합니다. 아니면 뭔가 빠졌나요? – pbaris

+0

죄송합니다. @pbaris. 방금 내 대답을 편집했습니다. 물론, 그 경우에는 전혀 실행되지 않을 것입니다. '@ Included' 또는 이와 비슷한 것을 담고있는 bean 만 직접 주입 할 수 있습니다. – Turini

관련 문제