CDI bean注入奇怪的行为 - 字段未初始化,但get / set方法有效

时间:2018-06-05 10:41:28

标签: jax-rs cdi

JavaEE7,Wildfly 11,jdk 10

我在REST类中注入了以下bean:

@Named("form")
@RequestScoped
public class SomeForm implements Serializable {

    private static final long serialVersionUID = 1L;

    @FormParam("firstName")
    @Pattern(regexp="[a-zA-Z ]+")
    String firstName;

    @FormParam("lastName")
    @Pattern(regexp="[a-zA-Z ]+")
    String lastName;

    @FormParam("country")
    @Pattern(regexp="[a-zA-Z ]+")
    String country;

    @FormParam("age")
    @Min(5)
    @Max(100)
    int age;

    @FormParam("gender")
    @Pattern(regexp="[mf]{1}") //probably change to .*
    String gender;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

以下是其他课程:

@Inject Validator vf;
@Inject SomeForm form;

@POST
@Controller
@UriRef("submitErrTestForm")
@Path("form-error-test")
public Response formProc(MultivaluedMap<String, String> params) throws Exception {

    form.setFirstName(params.get("firstName").get(0));
    form.setLastName(params.get("lastName").get(0));
    form.setCountry(params.get("country").get(0));
    form.setAge(Integer.valueOf(params.get("age").get(0)));
    form.setGender(params.get("gender").get(0));


    if (vf.validate(form).size() != 0) throw new Exception("Invalid field");
    return Response.ok("some-form-processed.hbs").build();
}

问题是验证每次都失败。在这里进行调试时form的样子如下:

form
SomeForm$Proxy$_$$_WeldClientProxy (id=18677)
serialVersionUID: 1
weld$$$10943: Method (id=18679)
weld$$$10944: Method (id=18680)
weld$$$10945: Method (id=18681)
weld$$$10946: Method (id=18682)
age: 0
BEAN_ID_FIELD: StringBeanIdentifier (id=18683)
constructed: true
country: null
firstName: null
gender: null
lastName: null
methodHandler: ProxyMethodHandler (id=18684)

每个字段都为空。然而,吸气剂和制定者工作。例如,form.getAge()将返回一个设定值,即使实例将其字段显示为0(未初始化)。这会导致验证程序每次都失败,因为虽然它能够看到带注释的表单字段,但实际字段是未初始化的。这可能是因为cdi为scoped bean代理了。

还有另一种情况,恰恰相反:

public Response formProc(@Valid @BeanParam SomeForm form) throws Exception {
    //...
}

在这种情况下验证工作,调试器将按预期显示字段及其值,但form.getAge()将返回0 - 好像它是一个新实例并且没有任何内容被初始化。

form
SomeForm$Proxy$_$$_WeldClientProxy (id=19387)
serialVersionUID: 1
weld$$$12490: Method (id=19388)
weld$$$12491: Method (id=19389)
weld$$$12492: Method (id=19390)
weld$$$12493: Method (id=19391)
age: 55
BEAN_ID_FIELD: StringBeanIdentifier (id=19392)
constructed: true
country: "safd" (id=19393)
firstName: "asdf" (id=19394)
gender: "m" (id=19395)
lastName: "asdf" (id=19396)
methodHandler: ProxyMethodHandler (id=19397)
form.getAge()
0

截至目前我只做new SomeForm()并且REST端点通过@FormParam("age") int age提取参数并且它有效...但我想使用CDI。我无法更改SomeForm的范围,必须为@RequestScoped。有办法吗?

0 个答案:

没有答案