有一项任务是在查询字符串(URL 字符串中的参数)中序列化自定义类。类的一些字段必须是强制性的,一些是可选的。例如:
public class UserQueryParameters {
String name; // *
int age; // Не обязательно
String sex; // Не обязательно
}
您需要以某种方式声明要序列化的字段(在 Java 现实中,这称为编组,排序),哪些不是,然后将生成的结构转换为形式的字符串
name=John&age=23
如何实施?
尝试使用lombok注释:
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class UserQueryParameters {
String name; // *
int age; // Не обязательно
String sex; // Не обязательно
}
接下来,通过builder,形成一个填充字段的类实例:
UserQueryParameters params = UserQueryParameters.builder()
.name("John")
.sex("m")
.build();
并通过反射形成查询字符串:
import java.lang.reflect.Field;
// ...
for (Field field : params.getClass().getDeclaredFields()) {
if (field.get(params) != null) {
addToQueryString(field.get(params));
}
}
但是,显然,这样的解决方案是不合适的,因为。例如,对于一个int字段,不会是null,而是0。
实际上,您的问题包含了一半的答案:)
为此,java 使用了注解机制。您需要创建自己的注释,用它们标记类中的字段,然后在编组器中通过反射遍历类对象的字段,从中选择带注释的字段,并
key=value从标记的字段中为请求生成对.我做了一个简单的例子。
QueryField使用两个参数创建注释required定义该字段是否是必需的。默认情况下true- 这样做是为了明确指定可选字段。name指定序列化时使用的名称。如果未设置,则使用字段名称。下面是一个如何使用注解的示例。具有字段
age和的name类sex。只有字段是必需name的,字段sex被序列化为gender.java中的注解由关键字定义
@interface:(Java 语言规范中的更多详细信息)
现在我们可以继续编写序列化程序,但作为测试驱动开发的粉丝,我将从test开始。贴在这里太大了,所以我把它放在pastebin上。
我将仅解释测试的想法。
现在测试已经准备好了,我们可以编写一个简单的序列化程序来说明这个想法。
那里的一切都很简单。首先,我们遍历对象的字段并查找带有注释的字段
QueryField。如果找到这样的字段,我们会尝试提取该字段。作为响应,JRE 可能会抛出异常——我们正在处理它们。然后我们同时检查该字段是否为空和可选。我们跳过这些字段。我们抛出一个关于空的必填字段的异常。
然后我们将值转换为字符串(我们为每个消防员筛选所有危险字符)并选择一个名称 - 在注释中指定或从字段名称中获取。我们将“name=valueText”对添加到结果字符串中。利润!
不知何故,这就是它的完成方式。
因为您正在处理字符串请求。我将首先序列化为带有字符串字段的中间类。为了不在转换中出现未处理的错误。
并且已经对其进行了进一步处理,检查了请求的值和其他值。
而且由于通常请求本身会默认为您完成。(查询将被解析为行)。您基本上需要自己检查和处理参数