在Java中,我们看到许多final可以使用关键字的地方,但它的使用并不常见.
例如:
String str = "abc";
System.out.println(str);
Run Code Online (Sandbox Code Playgroud)
在上述情况下,str可以final但通常不会这样做.
当一个方法永远不会被覆盖时,我们可以使用final关键字.类似地,如果一个类不会被继承.
在任何或所有这些案例中使用final关键字是否真的能提高性能?如果是这样,那怎么样?请解释.如果正确使用final真正重要的性能,应在Java程序员开发什么习惯,使关键字的最好用?
我想创建一个自定义序列化程序,它可以完成一些工作,然后将其余部分用于默认序列化.
例如:
@JsonSerialize(using = MyClassSerializer.class)
public class MyClass {
...
}
public class MyClassSerializer extends JsonSerializer<MyClass> {
@Override
public void serialize(MyClass myClass, JsonGenerator generator,
SerializerProvider provider)
throws JsonGenerationException, IOException {
if (myClass.getSomeProperty() == someCalculationResult) {
provider.setAttribute("special", true);
}
generator.writeObject(myClass);
}
}
Run Code Online (Sandbox Code Playgroud)
有了为聚合对象创建其他自定义序列化程序的想法,这些序列化程序根据'speical'属性值表现不同.但是,上面的代码不起作用,因为毫无疑问会进入无限递归.
有没有办法告诉杰克逊在设置属性后使用默认序列化?我真的不想枚举像许多自定义序列化程序一样的所有属性,因为类相当复杂,我不想每次更改类时都要对序列化程序进行双重维护.
我有很多类来自供应商,他们喜欢在属性访问上随机抛出RuntimeExceptions.
public Object getSomeProperty() {
if (!someObscureStateCheck()) {
throw new IllegalStateExcepion();
}
return calculateTheValueOfProperty(someRandomState);
}
Run Code Online (Sandbox Code Playgroud)
我无法更改类,无法添加注释,为每个类定义mixins是不现实的,因为堆栈的这一部分经常变化.
如果杰克逊的getter抛出异常,我如何让杰克逊忽略一个属性?
鉴于以下POJO ..
public class City {
private String title;
private List<Person> people;
}
Run Code Online (Sandbox Code Playgroud)
...
public class Person {
private String name;
private int age;
}
Run Code Online (Sandbox Code Playgroud)
我想让Jackson将类的实例序列化为以下示例 JSON:
{
"title" : "New York",
"personName_1" : "Jane Doe",
"personAge_1" : 42,
"personName_2" : "John Doe",
"personAge_2" : 23
}
Run Code Online (Sandbox Code Playgroud)
JSON格式由外部API定义,我无法更改.
我已经发现我可以使用自定义序列化程序对列表字段进行注释,例如:
@JsonSerialize(using = PeopleSerializer.class)
private List<Person> people;
Run Code Online (Sandbox Code Playgroud)
......这是我尝试过的基本实现:
public class PeopleSerializer extends JsonSerializer<List<Person>> {
private static final int START_INDEX = 1;
@Override
public void serialize(List<Person> people,
JsonGenerator generator,
SerializerProvider …Run Code Online (Sandbox Code Playgroud) 我试图实现一个通用方法,将给定对象序列化为JSON,但只有那些在集合中传递的属性.如果可能的话,我希望在没有指定@JsonFilter类的情况下获得此功能.为此,我试图使用FilterExceptFilter杰克逊2.4.1.依赖关系:
这就是我现在所拥有的:
public static String serializeOnlyGivenFields(Object o,
Collection<String> fields) throws JsonProcessingException {
if ((fields == null) || fields.isEmpty()) return null;
Set<String> properties = new HashSet<String>(fields);
SimpleBeanPropertyFilter filter =
new SimpleBeanPropertyFilter.FilterExceptFilter(properties);
SimpleFilterProvider fProvider = new SimpleFilterProvider();
fProvider.addFilter("fieldFilter", filter);
fProvider.setDefaultFilter(filter);
ObjectMapper mapper = new ObjectMapper();
mapper.setFilters(fProvider);
String json = mapper.writeValueAsString(o);
return json;
}
Run Code Online (Sandbox Code Playgroud)
但是,永远不会应用过滤器.它总是序列化所有属性.
Set<String> fields = new HashSet<String>(); fields.add("name");
String json = Serializer.serializeOnlyGivenFields(e, fields);
System.out.println(json);
Run Code Online (Sandbox Code Playgroud)
{"name":"测试实体","描述":"测试说明"}
我也曾尝试注册FilterProvider …
我想要的是有条件地为类的对象使用默认的 BeanSerializer:
class MyCustomSerializer extends StdSerializer<AbstractEntity> {
public MyCustomSerializer() {
super(AbstractEntity.class);
}
@Override
public void serialize(AbstractEntity o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (someCondition()) {
serializeNormalWay(); //how?
} else {
//custom serialization
}
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过做类似的事情:
serializerProvider.defaultSerializeValue(o, jsonGenerator);
Run Code Online (Sandbox Code Playgroud)
但这调用了 MyCustomSerializer 的方法,并且我有永无休止的递归。如何获得可用于普通 bean 序列化的适当 Serializer 对象?
所以,标题基本上描述了我需要的东西.比如说,要序列化的bean看起来像这样:
public class SomeBean {
public String someString;
}
Run Code Online (Sandbox Code Playgroud)
我希望Jackson 像这样序列化SomeBean的一个实例:
{
someString: '<the value>',
__hash_someString: '<a proprietary hash of <the value>>'
}
Run Code Online (Sandbox Code Playgroud)
此功能应该是通用的.我不想为SomeBean编写特定的序列化程序,因为这需要在多个位置进行.将" __hash_someString " 添加到类本身不是一个选项,因为它会污染模型.
履行
我希望杰克逊能正常处理豆子.但是当遇到特定的注释(@GenerateHash)时,它应该像之前一样向对象添加另一个字段.所以它想这样:
public class SomeBean {
@GenerateHash
public String someString;
}
Run Code Online (Sandbox Code Playgroud)
这条路到目前为止
有很多类似的主题,但没有一个尝试这样的事情.我并没有真正进入Jackson Serialization的内部工作,但似乎你只能选择修改一个整体的对象.我还没有找到一种方法来拦截字段的序列化过程,只有该字段的值.
我试图使用BeanSerializerModifier实现这一点,并尝试使用@Serializer.但是,我通常最终会陷入无限循环.
我咨询的资源是(不限于):
简而言之, 我怎样才能让杰克逊序列化
public class SomeBean {
@GenerateHash
public String someString;
public String unaffectedString;
}
Run Code Online (Sandbox Code Playgroud)
对此:
{
someString: '<the value>',
__hash_someString: '<a …Run Code Online (Sandbox Code Playgroud) 类似于 @JsonAppend 的简化版本
public class Bean {
@JsonAppend(key = [...], value = [...])
public Map<?, ?> map = new HashMap<>();
}
Run Code Online (Sandbox Code Playgroud)
那就太好了-有什么简单的方法可以实现这一点吗?
我读过很多 SO 条目,例如。
但没有找到符合我需求的东西。
我的请求的原因是无法区分某些给定的 JSON 是源自 Map 还是 POJO 序列化。如果有必要(在极少数情况下),向地图添加魔法额外字段将是实现此目的的简单方法。
我需要编辑 POJO 中“现有字段”的名称,而不是添加“extra_field”。是否可以使用下面参考的链接方法?
请注意,我不想使用@JsonProperty注释。
要求是,我有一个 POJO,并且希望每次都使用不同的字段名称,而不需要更改 POJO。例如,我c_id在 POJO 中有一个字段,有时需要写为 as cust_id,有时则需要写为my_id。
另请注意,我无法更改 POJO 的实现,因为它已经在多个模块中使用并且具有通用实现。
POJO 示例:
class MyPojo {
String id;
// getter and setters
}
Run Code Online (Sandbox Code Playgroud)
预期输出如下:(字段名称可以更改)