2013-10-15 79 views
2

我的項目有下一個問題需要研究。我需要在CDI的簡單servlet項目中使用BeansValidation。我想讓bean驗證與使用範圍註釋標註的cdi bean一起工​​作,但現在,當我嘗試驗證這些bean時(即使它們有一些錯誤),驗證程序聲稱完全沒有錯誤。CDI和servlet應用程序中的BeanValidation

另外,將EL語言的bean屬性設置爲請求中的值將會很好,這似乎適用於具有範圍註釋的bean,但它不適用於其他任何bean。

我認爲這是CDI代理的問題,但我不知道如何解決它。我使用maven構建我的應用程序並將其部署到Jboss 7.1.1.Final。

這裏是我的項目全部來源:

豆用範圍註釋:

package pl.lab3.bean; 

import javax.enterprise.context.RequestScoped; 
import javax.inject.Named; 
import javax.validation.constraints.Size; 

@Named 
@RequestScoped 
public class Scoped { 
    @Size(max = 2) 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

豆無範圍註釋:

package pl.lab3.bean; 

import javax.inject.Named; 
import javax.validation.constraints.Size; 

@Named 
public class Data { 
    @Size(max = 2) 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

的Servlet:

package pl.lab3.servlet; 

import pl.lab3.bean.Data; 
import pl.lab3.bean.Scoped; 

import javax.el.ELContext; 
import javax.el.ExpressionFactory; 
import javax.inject.Inject; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.validation.ConstraintViolation; 
import javax.validation.Validator; 
import java.io.IOException; 
import java.util.Set; 

public class ServletDispatcher extends HttpServlet { 
    @Inject 
    private Validator validator; 
    @Inject 
    private ELContext elContext; 
    @Inject 
    private ExpressionFactory expressionFactory; 
    @Inject 
    private Scoped scoped; 
    @Inject 
    private Data data; 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, 
      IOException { 
     this.request(request, response); 
    } 

    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, 
      IOException { 
     this.request(request, response); 
    } 

    private void request(HttpServletRequest request, HttpServletResponse response) 
      throws IOException { 
     try { 
      expressionFactory.createValueExpression(elContext, "${scoped.name}", String.class) 
        .setValue(elContext, "test"); 
      String goodValue = scoped.getName(); //returns test, as expected 
      //but in debugger it's still null(first screen) 
      Set<ConstraintViolation<Scoped>> emptySet = validator.validate(scoped); //doesn't work, returns empty set 

      scoped.setName("test2"); 
      String goodValue2 = scoped.getName(); //obviously works, but still null in debugger(same first screen, just nothing happened) 
      Set<ConstraintViolation<Scoped>> emptySet2 = 
        validator.validate(scoped); //doesn't work too, returns empty set 

      expressionFactory.createValueExpression(elContext, "${data.name}", String.class) 
        .setValue(elContext, "test"); 
      String badValue = data.getName(); //above doesn't work, and in debugger too(second screen) 
      Set<ConstraintViolation<Data>> emptySet3 = validator.validate(data); //empty set... 

      data.setName("test2"); 
      String goodValue3 = data.getName(); //obviously works, and I can see good value in debugger(third screen) 
      Set<ConstraintViolation<Data>> errors = validator.validate(data); //and here I've got expected error 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Scren從debbuger鏡頭在servlet代碼提到:

屏蔽1:

screen1 with scoped bean and null value

屏蔽2:

enter image description here

屏幕3:

enter image description here

還有一些(我認爲)不太重要的文件:

的web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
    <servlet> 
     <servlet-name>dispatcher</servlet-name> 
     <servlet-class>pl.lab3.servlet.ServletDispatcher</servlet-class> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>dispatcher</servlet-name> 
     <url-pattern>/*</url-pattern> 
    </servlet-mapping> 

</web-app> 

的beans.xml

<?xml version="1.0"?> 
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd"> 
</beans> 

的pom.xml

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>lab</groupId> 
    <version>1.0</version> 
    <artifactId>lab3-validation</artifactId> 
    <packaging>war</packaging> 
    <name>lab3-validation</name> 

    <dependencies> 
     <dependency> 
      <groupId>org.jboss.seam.validation</groupId> 
      <artifactId>seam-validation</artifactId> 
      <version>3.1.0.Final</version> 
     </dependency> 
     <dependency> 
      <groupId>org.jboss.spec</groupId> 
      <artifactId>jboss-javaee-web-6.0</artifactId> 
      <version>3.0.2.Final</version> 
      <type>pom</type> 
      <scope>provided</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.jboss.weld.servlet</groupId> 
      <artifactId>weld-servlet</artifactId> 
      <version>2.0.1.Final</version> 
     </dependency> 
    </dependencies> 

    <repositories> 
     <repository> 
      <id>JBoss repository</id> 
      <url>http://repository.jboss.org/nexus/content/groups/public/</url> 
     </repository> 
    </repositories> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>3.0</version> 
       <configuration> 
        <source>1.7</source> 
        <target>1.7</target> 
       </configuration> 
      </plugin> 
     </plugins> 
     <finalName>validation</finalName> 
    </build> 

</project> 

回答

1

你可以嘗試添加您對屬性級別的限制(即在getter方法而不是字段上)。

+0

您的解決方法正常工作。但是,物業級別註釋也會很好。我試圖通過實際對象來驗證方法,而不是cdi代理。我通過調用具有適當參數的BeanManager.getContext()。get()來接收真實對象,然後它可以工作。對於好的和不可見的解決方案,我認爲自定義驗證器生產者將會很好,在這個生產者中,我將把代理返回給驗證器對象,並且在這個代理中,當方法的第一個參數是cdi代理時,我會將其更改爲實際對象。但問題是如何檢查某個對象是cdi代理還是真實對象? – gandalfml

4

這是因爲您的CDI對象由CDI容器管理。當驗證器試圖找到類時,它會得到一些代理類名稱,而不是你正在處理的對象。您不應該讓您的模型/傳輸對象CDI受到管理。

+0

我認爲這個問題靠近cdi代理。但問題是如何解決這個問題?我有想法從代理獲得真正的對象,然後將其傳遞給驗證器。在代理驗證器中這樣做會很好(正如我在commet中寫到@Gunnar的答案)。如果驗證者在cdi beans上工作(或模仿工作),我認爲它會很好。 – gandalfml

相關問題