Spring 5 不可变形式,当没有参数构造函数时也使用全参数构造函数
Spring 5 immutable form to use an all arg constructor when there is No argument constructor as well
在不可变的 class/object 中,我有一个无参数构造函数将值初始化为 default/null,另一个必需的参数构造函数将所有值初始化为构造函数的参数。
使用表单绑定时(通过在控制器的请求参数中指定),spring 总是调用无参数构造函数而不初始化值。如何确保 spring 仅调用所需的参数构造函数?
这是 spring 版本 5.1.5。我也尝试在 "required argument constructor" 上添加 @ConstructorProperties,但无济于事。
我的不可变 form/bean 对象:
public class ImmutableObj {
private final Integer id;
private final String name;
// no arg constructor
// spring calls this one when resolving request params
public ImmutableObj() {
this(null, null);
}
// required args constructor
// I want spring to call this one when resolving request params
@ConstructorProperies({"id", "name"})
public ImmutableObj(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
}
还有我的控制器:
@Controller
public class MyController {
@GetMapping("myStuff")
public String getMyStuff(ImmutableObj requestParams) {
// here the value of request params
// has nulls due to no arg constructor being called
return "someStuff";
}
}
调用“/myStuff?id=123&name=hello”时
预计 - requestParams.getId()=123, requestParams.getName()=hello
实际 - requestParams.getId()=null, requestParams.getName()=null
更新!!!!!!!!!!!!!!!
删除无参数构造函数后,我现在 运行 遇到组合问题:
public class ImmutableObj {
private final SomeOtherObj someOtherObj;
public ImmutableObj(SomeOtherObj obj) {
someOtherObj = obj;
}
}
public class SomeOtherObj {
private final Integer id;
private final String name;
public SomeOtherObj(Integer id, String name) {
this.id = id;
this.name = name;
}
}
并且 spring 抛出:
Could not instantiate property type [SomeOtherObj] to auto-grow nested property path; nested exception is java.lang.NoSuchMethodException: SomeOtherObj.<init>()
Spring is always calling the no argument constructor and not initializing the values.
当Spring看到class有多个构造函数时,它会去寻找一个无参数的。如果Spring没有找到,就会抛出异常。
当Spring看到class只有一个构造函数时,无论它有多少个参数,它都会接受它。
How can I ensure spring to call the required argument constructor only?
唯一的办法是在class中只有一个构造函数。为了使 Spring.
明确
作为旁注,
如果字段名称对应于 URL 参数名称,则不需要 @ConstructorProperies({"id", "name"})
。 Spring 可以解决这个问题。
public ImmutableObj() {
this(null, null);
}
不是个好主意。 ImmutableObj.empty()
会更好。
作为奖励,如果您想了解幕后发生的事情,这里是我所说的片段
if (ctor == null) {
Constructor<?>[] ctors = clazz.getConstructors();
if (ctors.length == 1) {
ctor = ctors[0];
} else {
try {
ctor = clazz.getDeclaredConstructor();
} catch (NoSuchMethodException var10) {
throw new IllegalStateException("No primary or default constructor found for " + clazz, var10);
}
}
}
在不可变的 class/object 中,我有一个无参数构造函数将值初始化为 default/null,另一个必需的参数构造函数将所有值初始化为构造函数的参数。
使用表单绑定时(通过在控制器的请求参数中指定),spring 总是调用无参数构造函数而不初始化值。如何确保 spring 仅调用所需的参数构造函数?
这是 spring 版本 5.1.5。我也尝试在 "required argument constructor" 上添加 @ConstructorProperties,但无济于事。
我的不可变 form/bean 对象:
public class ImmutableObj {
private final Integer id;
private final String name;
// no arg constructor
// spring calls this one when resolving request params
public ImmutableObj() {
this(null, null);
}
// required args constructor
// I want spring to call this one when resolving request params
@ConstructorProperies({"id", "name"})
public ImmutableObj(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
}
还有我的控制器:
@Controller
public class MyController {
@GetMapping("myStuff")
public String getMyStuff(ImmutableObj requestParams) {
// here the value of request params
// has nulls due to no arg constructor being called
return "someStuff";
}
}
调用“/myStuff?id=123&name=hello”时
预计 - requestParams.getId()=123, requestParams.getName()=hello
实际 - requestParams.getId()=null, requestParams.getName()=null
更新!!!!!!!!!!!!!!!
删除无参数构造函数后,我现在 运行 遇到组合问题:
public class ImmutableObj {
private final SomeOtherObj someOtherObj;
public ImmutableObj(SomeOtherObj obj) {
someOtherObj = obj;
}
}
public class SomeOtherObj {
private final Integer id;
private final String name;
public SomeOtherObj(Integer id, String name) {
this.id = id;
this.name = name;
}
}
并且 spring 抛出:
Could not instantiate property type [SomeOtherObj] to auto-grow nested property path; nested exception is java.lang.NoSuchMethodException: SomeOtherObj.<init>()
Spring is always calling the no argument constructor and not initializing the values.
当Spring看到class有多个构造函数时,它会去寻找一个无参数的。如果Spring没有找到,就会抛出异常。
当Spring看到class只有一个构造函数时,无论它有多少个参数,它都会接受它。
How can I ensure spring to call the required argument constructor only?
唯一的办法是在class中只有一个构造函数。为了使 Spring.
明确作为旁注,
如果字段名称对应于 URL 参数名称,则不需要
@ConstructorProperies({"id", "name"})
。 Spring 可以解决这个问题。public ImmutableObj() { this(null, null); }
不是个好主意。 ImmutableObj.empty()
会更好。
作为奖励,如果您想了解幕后发生的事情,这里是我所说的片段
if (ctor == null) {
Constructor<?>[] ctors = clazz.getConstructors();
if (ctors.length == 1) {
ctor = ctors[0];
} else {
try {
ctor = clazz.getDeclaredConstructor();
} catch (NoSuchMethodException var10) {
throw new IllegalStateException("No primary or default constructor found for " + clazz, var10);
}
}
}