2

我的学习项目有下一个问题。我需要在带有 CDI 的简单 servlet 项目中使用 BeansValidation。我希望 bean 验证与使用范围注释注释的 cdi bean 一起工作,但是现在,当我尝试验证这些 bean(即使它们有一些错误)时,验证器声称根本没有错误。

另外,使用 EL 语言将 bean 属性设置为来自请求的值会很好,这似乎适用于具有范围注释的 bean,但它不适用于任何其他 bean。

我认为这是 CDI 代理的一些问题,但我不知道如何解决它。我使用 maven 构建我的应用程序并将其部署在 Jboss 7.1.1.Final 上。

以下是我项目中的所有资源:

带有范围注释的 Bean:

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

没有范围注释的 Bean:

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

小服务程序:

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();
        }
    }
}

servlet 代码中提到的调试器的截图:

屏幕1:

具有范围 bean 和空值的 screen1

屏幕2:

在此处输入图像描述

屏幕3:

在此处输入图像描述

还有一些(我认为)不太重要的文件:

网页.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>

豆类.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>
4

2 回答 2

4

这是因为您的 CDI 对象由 CDI 容器管理。当验证器尝试查找类时,它会获取一些代理类名称,而不是您正在处理的对象。你不应该让你的模型/传输对象 CDI 管理。

于 2013-10-15T22:26:19.793 回答
1

您可以尝试在属性级别添加约束(即在 getter 方法而不是字段上)。

于 2013-10-15T19:33:30.780 回答