Gson 不遵守生成器中的规则
Gson not honouring rules in builder
我有一个名为 Student
的 class,它有一些必填字段,其他字段是可选的。为了确保 class Student
的对象在没有提供必填字段的情况下被创建,我使用了一个构建器。这是 class Student
:
package prj1.dob;
import java.util.Date;
public class Student {
private final int id;
private final String name;
private final String surname;
private final Date dob;
private final Double gpa;
private final String email;
public static class Builder {
//required fields
private int id;
private String name;
private String surname;
//optional fields
private Date dob;
private Double gpa;
private String email;
public Builder(int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
public Builder dob(Date dob) {
this.dob = dob;
return this;
}
public Builder gpa(Double gpa) {
this.gpa = gpa;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Student build() throws Exception {
return new Student(this);
}
}
private Student(Builder b) throws Exception {
this.id = b.id;
this.name = b.name;
this.surname = b.surname;
this.dob = b.dob;
this.gpa = b.gpa;
this.email = b.email;
validate();
}
private void validate() throws Exception {
if (id < 10 || name == null || surname == null) {
throw new Exception("You should provide an id, name and surname.");
}
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", surname=" + surname + ", dob=" + dob + ", gpa=" + gpa + ", email=" + email + "]";
}
}
有了 class Student
的这个实现,我希望不应该有创建无效 Student
对象的方法(即必填字段不应该是 null
).但是,下面提供的代码不会抛出 Exception
,当我打印 Student
的内容时,必填字段是 null
.
JSON 对象:
{"id":-1,"name":null,"surname":null,"dob":null,"gpa":null,"email":null}
这是从 JSON:
创建 POJO 的代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String param = request.getParameter("std").toString();
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").serializeNulls().create();
Student student = gson.fromJson(param, Student.class);
// student.validate();
response.getWriter().write(student.toString());
} catch (Exception ex) {
response.getWriter().write(ex.getMessage());
}
}
我希望它抛出一个 Exception
但它创建了一个 Student
的对象,当打印时这是内容:
Student [id=-1, name=null, surname=null, dob=null, gpa=null, email=null]
这是 Gson 库中的错误还是我做错了什么?
如果这是应该的,那么使用 builder 方法有什么意义,因为仍然可以在不遵循规则的情况下创建 class 的对象(提供必填字段)?
GSON 使用 reflection 而不是您的构建器来构建 Student
。
虽然您无法阻止 Student 的其他用户随意使用反射创建东西,但您可以提供一个 JsonDeserializer
,它知道 Student
的规则并使用您的构建器创建一个。
我有一个名为 Student
的 class,它有一些必填字段,其他字段是可选的。为了确保 class Student
的对象在没有提供必填字段的情况下被创建,我使用了一个构建器。这是 class Student
:
package prj1.dob;
import java.util.Date;
public class Student {
private final int id;
private final String name;
private final String surname;
private final Date dob;
private final Double gpa;
private final String email;
public static class Builder {
//required fields
private int id;
private String name;
private String surname;
//optional fields
private Date dob;
private Double gpa;
private String email;
public Builder(int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
public Builder dob(Date dob) {
this.dob = dob;
return this;
}
public Builder gpa(Double gpa) {
this.gpa = gpa;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Student build() throws Exception {
return new Student(this);
}
}
private Student(Builder b) throws Exception {
this.id = b.id;
this.name = b.name;
this.surname = b.surname;
this.dob = b.dob;
this.gpa = b.gpa;
this.email = b.email;
validate();
}
private void validate() throws Exception {
if (id < 10 || name == null || surname == null) {
throw new Exception("You should provide an id, name and surname.");
}
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", surname=" + surname + ", dob=" + dob + ", gpa=" + gpa + ", email=" + email + "]";
}
}
有了 class Student
的这个实现,我希望不应该有创建无效 Student
对象的方法(即必填字段不应该是 null
).但是,下面提供的代码不会抛出 Exception
,当我打印 Student
的内容时,必填字段是 null
.
JSON 对象:
{"id":-1,"name":null,"surname":null,"dob":null,"gpa":null,"email":null}
这是从 JSON:
创建 POJO 的代码protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String param = request.getParameter("std").toString();
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").serializeNulls().create();
Student student = gson.fromJson(param, Student.class);
// student.validate();
response.getWriter().write(student.toString());
} catch (Exception ex) {
response.getWriter().write(ex.getMessage());
}
}
我希望它抛出一个 Exception
但它创建了一个 Student
的对象,当打印时这是内容:
Student [id=-1, name=null, surname=null, dob=null, gpa=null, email=null]
这是 Gson 库中的错误还是我做错了什么?
如果这是应该的,那么使用 builder 方法有什么意义,因为仍然可以在不遵循规则的情况下创建 class 的对象(提供必填字段)?
GSON 使用 reflection 而不是您的构建器来构建 Student
。
虽然您无法阻止 Student 的其他用户随意使用反射创建东西,但您可以提供一个 JsonDeserializer
,它知道 Student
的规则并使用您的构建器创建一个。