此处将为大家介绍关于创建一个自定义的Jackson注释的详细内容,并且为您解答有关jackson自定义注解的相关问题,此外,我们还将为您介绍关于django如何创建一个自定义的404/500错误页面、
此处将为大家介绍关于创建一个自定义的Jackson注释的详细内容,并且为您解答有关jackson自定义注解的相关问题,此外,我们还将为您介绍关于django 如何创建一个自定义的404/500错误页面、Duilib 入门教程: 怎么创建一个自定义的窗口、Jackson 不会映射到自定义的侦听器映射对象?、Jackson注释的使用的有用信息。
本文目录一览:- 创建一个自定义的Jackson注释(jackson自定义注解)
- django 如何创建一个自定义的404/500错误页面
- Duilib 入门教程: 怎么创建一个自定义的窗口
- Jackson 不会映射到自定义的侦听器映射对象?
- Jackson注释的使用
创建一个自定义的Jackson注释(jackson自定义注解)
一个项目需要大量使用以下Jackson注释组合。因此,有没有一种方法可以创建另一个注释来避免丑陋的复制/粘贴:
public class A { @JsonProperty("_id") @JsonSerialize(using=IdSerializer.class) @JsonDeserialize(using=IdDeserializer.class) String id;}public class B { @JsonProperty("_id") @JsonSerialize(using=IdSerializer.class) @JsonDeserialize(using=IdDeserializer.class) String id;}public class C { @CustomId // don''t repeat that configuration endlessly String id;}
更新: 我已经尝试过了,但是没有成功:-(
@Retention(RetentionPolicy.RUNTIME)@JacksonAnnotationsInside@JsonProperty("_id")@JsonSerialize(using=IdSerializer.class, include=JsonSerialize.Inclusion.NON_NULL)@JsonDeserialize(using=IdDeserializer.class)public @interface Id {}public class D { @Id private String id;}
答案1
小编典典使用@JacksonAnnotationsInside
解决问题:
public class JacksonTest { @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonProperty("_id") @JsonSerialize(using=IdSerializer.class, include=Inclusion.NON_NULL) @JsonDeserialize(using=IdDeserializer.class) public @interface Id { } public static class Answer { @Id String id; String name; public Answer() {} } @Test public void testInside() throws IOException { ObjectMapper mapper = new ObjectMapper(); VisibilityChecker<?> checker = mapper.getSerializationConfig().getDefaultVisibilityChecker(); mapper.setVisibilityChecker(checker.withFieldVisibility(JsonAutoDetect.Visibility.ANY)); String string = "{ ''name'' : ''John'' , ''_id'' : { ''sub'' : ''47cc''}}".replace(''\'''', ''"''); Answer answer = mapper.reader(Answer.class).readValue(string); Assertions.assertThat(answer.id).isEqualTo("47cc"); }}
django 如何创建一个自定义的404/500错误页面
在您的主要内容下views.py添加您自己的以下两个视图的自定义实现,并设置模板404.html和500.html以及您想要显示的内容。
代码:views.py
from django.shortcuts import render_to_response from django.template import RequestContext def handler404(request, *args, **argv): response = render_to_response('404.html', {}, context_instance=RequestContext(request)) response.status_code = 404 return response def handler500(request, **argv): response = render_to_response('500.html', context_instance=RequestContext(request)) response.status_code = 500 return response
handler404和handler500导出了Django字符串配置变量django/conf/urls/__init__.py。这就是上面配置的原因。
要使上述配置生效,您应该在urls.py文件中定义以下变量,并将导出的Django变量指向定义这些Django功能视图的字符串Python路径,如下所示:
在urls.py添加以下代码
from django.conf.urls import ( handler400, handler403, handler404, handler500 ) handler400 = 'my_app.views.bad_request' handler403 = 'my_app.views.permission_denied' handler404 = 'my_app.views.page_not_found' handler500 = 'my_app.views.server_error'
Django 2.0的更新
在Django 2.0中更改了处理程序视图的签名:https: //docs.djangoproject.com/en/2.0/ref/views/#error-views
如果您使用上述视图,handler404将失败并显示以下消息:
“handler404()得到了一个意外的关键字参数'exception'”
在这种情况下修改您的视图,如下所示:
def handler404(request, exception, template_name="404.html"): response = render_to_response("404.html") response.status_code = 404 return response
疑难杂症:
不要忘记DEBUG必须设置为False才能使这些工作,否则,将使用正常的调试处理程序。
官方文档:https://docs.djangoproject.com/en/2.2/topics/http/views/#customizing-error-views
Duilib 入门教程: 怎么创建一个自定义的窗口
一直想找一个好用UI 界面库,看过Direct UI,也想过 金山的界面库,后来找到了这个Duilib
现在的软件界面很多都是利用XML 来布局和定位。
像迅雷7,QQ,金山卫士等
- <thunder_skin> - <skin id="default" name="image" type="bkg"> - <title> <text>洲-缥缈</text> </title> - <bkg> <image>image\bkg.jpg</image> </bkg> <owner_skin>default::default</owner_skin> <default_color_scheme>green</default_color_scheme> </skin> </thunder_skin>
Duilib 也是利用XML来记录控件的位置信息,然后在程序中解析XML 动态的产生相应的控件,来实现布局。
首先 google code项目托管地址: http://code.google.com/p/duilib/ 下载到最新的源代码。
解压后,我们可以看到里面有5个界面的demo 分别是模仿360 安全卫士,QQ,浩方游戏平台的界面,还有两个是演示列表控件和Flash插件的。
DuiLib 是整个项目的工程,里面还有一个演示的demo。 以后的程序都可以以这个为原型修改。
而我们的界面是通过 UIDesigner 来 编辑的
原文链接: http://blog.csdn.net/toss156/article/details/7003130
Jackson 不会映射到自定义的侦听器映射对象?
请尝试以下操作:通过构建自定义 MapType
为 Jackson 映射器提供更多类型支持。此后,您可以将其用于转换。
我已经实现了以下内容,它确实有效,并且您帖子中提到的 IllegalArgumentException
已消失:
MapType javaType = mapper.getTypeFactory().constructMapType(MapWithListeners.class,String.class,Object.class);
MapWithListeners<String,Object> map = mapper.convertValue(mainObj,javaType);
Jackson注释的使用
Jackson提供了一系列注解,可以使用这些注解来设置将JSON读入对象的方式或从对象生成什么JSON的方式,下面介绍一些常用的注解。
3.1 序列化
@JsonAnyGetter
@JsonAnyGetter 注解运行可以灵活的使用Map类型的作为属性字段,允许getter方法返回Map,该Map然后用于以与其他属性类似的方式序列化JSON的其他属性。通过序列化该实体Bean,我们将会得到Map属性中的所有Key作为属性值,测试序列化代码如下
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTester {
public static void main(String args[]) throws JsonProcessingException {
ExtendableBean bean = new ExtendableBean("My bean");
bean.add("attr1", "val1");
bean.add("attr2", "val2");
String result = new ObjectMapper().writeValueAsString(bean);
System.out.println(result);
}
}
class ExtendableBean {
public String name;
private Map<string, string> properties;
@JsonAnyGetter
public Map<string, string> getProperties() {
return properties;
}
public ExtendableBean(String name) {
this.name = name;
this.properties = new HashMap<string, string>();
}
public void add(String key, String value) {
this.properties.put(key, value);
}
}
最终输出结果如下
{
"name":"My bean",
"attr2":"val2",
"attr1":"val1"
}
如果不使用 @JsonAnyGetter 注解,那么最终序列化结果将会在properties属性下面,结果如下:
{
"name": "My bean",
"properties": {
"attr2": "val2",
"attr1": "val1"
}
}
@JsonRawValue
@JsonRawValue注解可以指定字符串属性类为json,如下代码:
import java.io.IOException;
import java.text.ParseException;
import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTester {
public static void main(String args[]) throws IOException, ParseException {
RawBean bean = new RawBean("My bean", "{\"attr\":false}");
String result = new ObjectMapper().writeValueAsString(bean);
System.out.println(result);
}
}
class RawBean {
public String name;
@JsonRawValue
public String json;
public RawBean(String name, String json) {
super();
this.name = name;
this.json = json;
}
}
最终使用@JsonRawValue序列化结果如下:
{
"name":"My bean",
"json":{
"attr":false
}
}
没有使用@JsonRawValue序列化结果如下:
{
"name":"My bean",
"json":"{\"attr\":false}"
}
@JsonRootName
@JsonRootName 注解旨在给当前序列化的实体对象加一层包裹对象,允许在JSON上指定根节点。
@data
public class RootUser {
private String name;
private String title;
public RootUser(String name, String title) {
this.name = name;
this.title = title;
}
}
在上面的实体类中,正常情况下,如果要序列号RootUser对象,其结果格式为:
{
"name": "name1",
"title": "title1"
}
在RootUser加上 @JsonRootName 注解后,该类改动如下:
@JsonRootName(value = "root")
public class RootUser {
private String name;
private String title;
public RootUser(String name, String title) {
this.name = name;
this.title = title;
}
}
@JsonRootName 仅用于指定 JSON 根属性的名称,只有当SerializationFeature.WRAP_ROOT_VALUE、DeserializationFeature.UNWRAP_ROOT_VALUE 启用时才有效。若只开启了 Feature 功能但未使用 @JsonRootName 注解,默认会使用类名作为 RootName。
ObjectMapper objectMapper=new ObjectMapper();
// 启用 SerializationFeature.WRAP_ROOT_VALUE
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
// 启用 DeserializationFeature.UNWRAP_ROOT_VALUE
objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
String result=objectMapper.writeValueAsString(new RootUser("name1","title1"));
最终序列化JSON结果如下:
{
"root": {
"name": "name1",
"title": "title1"
}
}
@JsonSerialize
实际开发中,一定遇到过这样的问题:前端显示和后台存储数据单位不统一,而且各有各自的理由,统一不了,那就只能由后端转换。每次返回给前端时再转换一遍,返回给前端的json数据,在后端里定义的往往是一个对象,如何做到优雅的转换呢?例如,Double类型的数据返回值转换成字符串,只需两步操作:
- 写一个负责转换的类,里面写好规则。
public class CustomDoubleSerialize extends JsonSerializer<double> {
@Override
public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
BigDecimal d = new BigDecimal(value.toString());
gen.writeString(d.stripTrailingZeros().toPlainString());
}
}
- 在实体类上需要装换的字段上加上注解
/**
* 金额
*/
@JsonSerialize(using = CustomDoubleSerialize.class)
private Double amount;
又例如,假设某布尔值false和true,使其分别为0和1。
- 写一个负责转换的类,里面写好规则:将序列的真值序列化为1,将假值序列化为0。
public class OptimizedBooleanSerializer extends JsonSerializer<boolean> {
@Override
public void serialize(Boolean aBoolean, JsonGenerator gen, SerializerProvider provider) throws IOException {
if(aBoolean){
jsonGenerator.writeNumber(1);
} else {
jsonGenerator.writeNumber(0);
}
}
}
- 在实体类上需要装换的字段上加上注解
@JsonSerialize(using = OptimizedBooleanSerializer.class)
public boolean enabled = false;
注:@JsonSerialize注解,主要应用于数据转换,该注解作用在该属性的getter方法上。
@JsonGetter
@JsonGetter 注解用于告诉Jackson,应该通过调用getter方法而不是通过直接字段访问来获取某个字段值。 如果您的Java类使用getter和setter名称,则@JsonGetter注解很有用。
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTester {
public static void main(String args[]) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Student student = new Student("Mark", 1);
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(student);
System.out.println(jsonString);
}
}
class Student {
private String name;
private int rollNo;
public Student(String name, int rollNo) {
this.name = name;
this.rollNo = rollNo;
}
@JsonGetter("studentName")
public String getName() {
return name;
}
public int getRollNo() {
return rollNo;
}
}
使用 @JsonGetter 输出如下结果:
{
"rollNo" : 1,
"studentName" : "Mark"
}
而没有使用 @JsonGetter 输出如下结果:
{
"name" : "Mark",
"rollNo" : 1
}
3.2 反序列化
@JsonCreator
@JsonCreator 用于告诉Jackson该Java对象具有一个构造函数,该构造函数可以将JSON对象的字段与Java对象的字段进行匹配。配合@JsonProperty注解能到达在反序列化实体对象时,指定不变更属性名称的效果。例如有如下JSON:
{
"id":1,
"theName":"My bean"
}
在实体类中,我们没有属性名称是theName,但我们想把theName属性反序列化时赋值给name,此时实体类对象结构如下:
public class BeanWithCreator {
public int id;
public String name;
@JsonCreator
public BeanWithCreator(@JsonProperty("id") int id, @JsonProperty("theName") String name) {
this.id = id;
this.name = name;
}
}
在BeanWithCreator的构造函数中添加@JsonCreator注解,并且配合@JsonProperty注解进行属性指向,最终反序列化代码如下:
import java.io.IOException;
import java.text.ParseException;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTester {
public static void main(String args[]) throws IOException, ParseException {
String json = "{\"id\":1,\"theName\":\"My bean\"}";
BeanWithCreator bean = new ObjectMapper().readerFor(BeanWithCreator.class).readValue(json);
System.out.println(new ObjectMapper().writeValueAsString(bean));
}
}
class BeanWithCreator {
public int id;
public String name;
@JsonCreator
public BeanWithCreator(@JsonProperty("id") int id, @JsonProperty("theName") String name) {
this.id = id;
this.name = name;
}
}
@JsonAnySetter
@JsonAnySetter 表示Jackson为JSON对象中所有无法识别的字段调用相同的setter方法, “无法识别”是指尚未映射到Java对象中的属性或设置方法的所有字段。@JsonAnySetter注解可以将来源JSON最终转化为Map类型的属性结构。
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTester {
public static void main(String args[]) {
ObjectMapper mapper = new ObjectMapper();
String jsonString = "{\"RollNo\" : \"1\",\"Name\" : \"Mark\"}";
try {
Student student = mapper.readerFor(Student.class).readValue(jsonString);
System.out.println(student.getProperties());
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Student {
private Map<string, string> properties;
public Student() {
properties = new HashMap<>();
}
public Map<string, string> getProperties() {
return properties;
}
@JsonAnySetter
public void add(String property, String value) {
properties.put(property, value);
}
}
@JsonSetter
@JsonSetter注解是@JsonProperty的替代注解,用于告诉Jackson将特定方法标记为setter方法。当将JSON读入对象时,应将此setter方法的名称与JSON数据中的属性名称匹配。当我们需要读取一些JSON数据时,但是目标实体类与该数据的属性名称不同,该注解是非常有用的。
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTester {
public static void main(String args[]) throws JsonProcessingException {
String json = "{\"id\":1,\"name\":\"My bean\"}";
ObjectMapper mapper = new ObjectMapper();
MyBean myBean = mapper.readerFor(MyBean.class).readValue(json);
System.out.println(mapper.writeValueAsString(myBean));
}
}
class MyBean {
private int id;
private String thename;
/**
* 通过指定setTheName作为属性name的setter方法,反序列化时可以达到最终效果
*/
@JsonSetter("name")
public void setTheName(String name) {
this.thename = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTheName() {
return thename;
}
}
@JsonDeserialize
@JsonDeserialize注解和序列化注解@JsonSerialize的效果是一致的,作用与反序列化时,针对特定的字段,存在差异化的发序列化效果。首先,需要将@JsonDeserialize注解添加到要为其使用自定义反序列化器的字段,如下所示
public class PersonDeserialize {
public long id = 0;
public String name = null;
@JsonDeserialize(using = OptimizedBooleanDeserializer.class)
public boolean enabled = false;
}
其次,这是@JsonDeserialize注解中引用的OptimizedBooleanDeserializer类的实例
public class OptimizedBooleanDeserializer
extends JsonDeserializer<boolean> {
@Override
public Boolean deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws
IOException, JsonProcessingException {
String text = jsonParser.getText();
if("0".equals(text)) return false;
return true;
}
}
请注意,OptimizedBooleanDeserializer类使用通用类型Boolean扩展了JsonDeserializer。 这样做会使deserialize()方法返回一个布尔对象。 如果要反序列化其他类型(例如java.util.Date),则必须在泛型括号内指定该类型。
3.3 属性注解
@JsonIgnore
Jackson注解 @JsonIgnore 用来告诉 Jackson 在处理时忽略Java对象的某个属性(字段),在将JSON读取到Java对象中以及将Java对象写入JSON时,都将忽略该属性。
@Data
public class SellerInfoEntity {
private String id;
private String username;
private String password;
@JsonIgnore
private Timestamp createTime;
@JsonIgnore
private Timestamp updateTime;
public SellerInfoEntity() {
}
public SellerInfoEntity(String id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
}
使用注解前
{
"id":"1",
"username":"user1",
"password":"123456",
"createTime":null,
"updateTime":null
}
使用注解后,不会从JSON读取或写入JSON属性(createTime、updateTime)
{
"id":"1",
"username":"user1",
"password":"123456"
}
@JsonIgnoreProperties
与 @JsonIgnore 类似,都是告诉 Jackson 该忽略哪些属性,不同之处是 @JsonIgnoreProperties 是类级别的,放置在类声明上方,达到在序列化时忽略一个或多个字段的效果。
@Data
@JsonIgnoreProperties(value = {"createTime","updateTime"})
public class SellerInfoEntity {
private String id;
private String username;
private String password;
private String openid;
private Timestamp createTime;
private Timestamp updateTime;
public SellerInfoEntity() {
}
public SellerInfoEntity(String id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
}
在此示例中,属性createTime、updateTime都将被忽略,因为它们的名称在类声明上方的 @JsonIgnoreProperties 注解声明内列出。
在目标对象的类级别上添加注解:@JsonIgnoreProperties(ignoreUnknown = true),用于忽略字段不匹配情况。
@JsonInclude
使用@JsonInclude注解告诉Jackson仅在某些情况下包括属性。 例如,仅当属性为非null,非空或具有非默认值时,才应包括该属性。
@JsonInclude(Include.NON_NULL)
public class MyBean {
public int id;
public String name;
}
在MyBean中使用了Include.NON_NULL则代表该实体对象序列化时不会包含空值。
3.4 常规注解
@JsonProperty
类似于sql里字段的别名,可以指定某个属性和json映射的名称。当实体对象中没有标准的getter/setter方法时,我们可以使用该注解进行指定属性名称,方便进行序列化/反序列化。例如我们有个json字符串为{"user_name":"aaa"}
,而java中命名要遵循驼峰规则,则为userName,这时通过 @JsonProperty 注解来指定两者的映射规则即可。
public class SomeEntity {
@JsonProperty("user_name")
private String userName;
// ...
}
@JsonFormat
此注解用于属性上,针对日期字段可以通过使用@JsonFormat注解直接转化为指定的格式,例如 @JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")
。主要有下面几个常用的属性
属性 | 说明 |
---|---|
shap | 表示序列化后的一种类型 |
pattern | 表示日期的格式 |
timezone | 若未标明时区,则默认为 GMT 时区,中国需要GMT+8 |
locale | 根据位置序列化的一种格式 |
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy年MM月dd日 HH:mm:ss", timezone = "GMT+8")
private Date date;
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
private Date date2;
@JsonFormat(locale = "zh_CN")
private Date date3;
跟 JsonSerializer 类似,如下所示:
@JsonSerialize(using = CustomDateSerializer.class)
private Date dateOfBirth;
class CustomDateSerializer extends JsonSerializer{
private static final long serialVersionUID = 1L;
private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
@Override
public void serialize(Date value,
JsonGenerator generator, SerializerProvider arg2) throws IOException {
generator.writeString(formatter.format(value));
}
}
关于创建一个自定义的Jackson注释和jackson自定义注解的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于django 如何创建一个自定义的404/500错误页面、Duilib 入门教程: 怎么创建一个自定义的窗口、Jackson 不会映射到自定义的侦听器映射对象?、Jackson注释的使用的相关信息,请在本站寻找。
本文标签: