我当前正在使用杰克逊2.1.4,并且在将对象转换为JSON字符串时,在忽略字段方面遇到一些麻烦。
这是我的类,它充当要转换的对象:
public class JsonOperation {
public static class Request {
@JsonInclude(Include.NON_EMPTY)
String requestType;
Data data = new Data();
public static class Data {
@JsonInclude(Include.NON_EMPTY)
String username;
String email;
String password;
String birthday;
String coinsPackage;
String coins;
String transactionId;
boolean isLoggedIn;
}
}
public static class Response {
@JsonInclude(Include.NON_EMPTY)
String requestType = null;
Data data = new Data();
public static class Data {
@JsonInclude(Include.NON_EMPTY)
enum ErrorCode { ERROR_INVALID_LOGIN, ERROR_USERNAME_ALREADY_TAKEN, ERROR_EMAIL_ALREADY_TAKEN };
enum Status { ok, error };
Status status;
ErrorCode errorCode;
String expiry;
int coins;
String email;
String birthday;
String pictureUrl;
ArrayList performer;
}
}
}
这是我如何转换它:
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
JsonOperation subscribe = new JsonOperation();
subscribe.request.requestType ="login";
subscribe.request.data.username ="Vincent";
subscribe.request.data.password ="test";
Writer strWriter = new StringWriter();
try {
mapper.writeValue(strWriter, subscribe.request);
} catch (JsonGenerationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("JSON", strWriter.toString())
这是输出:
{"data":{"birthday":null,"coins":null,"coinsPackage":null,"email":null,"username":"Vincent","password":"test","transactionId":null,"isLoggedIn":false},"requestType":"login"}
如何避免这些空值? 我只想获取"订阅"目的所需的信息!
这正是我要寻找的输出:
{"data":{"username":"Vincent","password":"test"},"requestType":"login"}
我还尝试了@JsonInclude(Include.NON_NULL)并将所有变量都设置为null,但是它也不起作用! 感谢您的帮助!
如果该字段的值为null,如何告诉Jackson在序列化过程中忽略该字段,可能会重复吗?
您将注解放置在错误的位置-注解必须在类上,而不是在字段上。即:
@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case
public static class Request {
// ...
}
如注释中所述,在版本2.x +中,此注释的语法为:
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY
另一个选项是直接配置ObjectMapper,只需调用
mapper.setSerializationInclusion(Include.NON_NULL);
(根据记录,我认为此答案的流行程度表明该注释应逐字段应用* ahem @ fasterxml *)
真的没有办法使include.NON_NULL注释起作用吗?还是NON_EMTPY一个?因为我知道哪个将为空,但这取决于情况。我对要序列化/反序列化的每个对象使用相同的" JsonOperation"类,而Im仅根据情况初始化需要使用的变量。这是一个好方法吗,还是我应该做几个只包含我需要的变量的类(那样我就不必使用任何注释,因为永远不会有null / empty变量)
抱歉,我看到了现在的情况。看到我编辑的答案。
语法在最新版本中已更改为@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)和@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY如果您需要非空和非空,请使用@JsonSerialize(include = JsonSerialize .Inclusion.NON_DEFAULT)
不工作!我都测试了。
在类之前或属性起作用之前使用@JsonSerialize(include = Inclusion.NON_NULL)...
我这样做了,序列化工作正常,但是我仍然在ADB中收到警告。任何想法如何删除那些?
2.x +使用JsonInlcude,下面使用JsonSerialize,请编辑您的答案。
@WestFarmer IIRC是正确的。如果您不同意,请自行编辑并查看是否获得批准。欢迎来到SO :-)
@drewmoore,请再次检查,@JsonInclude(JsonSerialize.Inclusion.NON_NULL)应该是@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL),并且它也是旧的不赞成使用的方式。因此您应该写"在2.x以下版本中",而不是"在2.x +版本中"
2. +使用@JsonInclude(Include.NON_NULL)
我使用了@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL),但它似乎对我不起作用。是因为我正在使用@JsonProperty吗?我需要对bean成员使用@JsonProperty以指定JSON密钥。我究竟做错了什么?这是我的bean public class TransactionResponse { @JsonProperty("TRANS_STATUS") @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) private int transactionStatus; @JsonProperty("ORDER_ID") private long orderId; },我也尝试将@JsonSerialize放置在类之前,但在响应中,trans_status始终为0
您还可以设置全局选项:
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
您也可以尝试使用
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
如果您要测试我测试过的版本低于2+(1.9.5)的杰克逊,则可以在类上方轻松使用此注释。不是为属性指定的,只是为类定义的。
不推荐使用JsonSerialize的include属性,而推荐使用JsonInclude
就像我说过的:杰克逊的版本低于2+(1.9.5)
问题询问特定的版本2.1.4
您需要添加导入com.fasterxml.jackson.annotation.JsonInclude;。
加
@JsonInclude(JsonInclude.Include.NON_NULL)
在POJO之上
如果您嵌套了POJO,那么
@JsonInclude(JsonInclude.Include.NON_NULL)
需要添加每个值。
注意:
JAXRS(Jersey)自动处理此场景2.6及更高版本。
使用旧的org.codehaus.jackson.annotate包时,是否有类似的功能?
是的,您可以在getter方法示例的顶部添加private int id; @JsonIgnore public int getId(){返回ID; }
与现有答案相同
对于杰克逊2.x
@JsonInclude(JsonInclude.Include.NON_NULL)就在该字段之前。
与现有答案相同
我最近在版本2.6.6中遇到类似的问题。
@JsonInclude(JsonInclude.Include.NON_NULL)
在字段级别或类级别使用以上注释均无法按预期方式工作。 POJO在我应用注释的地方是可变的。当我将POJO的行为更改为不可变时,注释发挥了神奇的作用。
我不确定该库的最新版本或先前版本是否具有类似行为,但是对于2.6.6,您肯定需要具有不可变POJO才能使注释起作用。
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
在直接在全局级别将ObjectMapper设置为包含序列化的各种答案中提到的上述选项也可以使用,但我更喜欢在类或文件级别进行控制。
因此,如果您希望在JSON序列化时忽略所有空字段,请在类级别使用注释,但是如果您只希望在类中忽略少数字段,则可以在那些特定字段上使用它。这样,如果您想更改特定响应的行为,它的可读性和维护便更加容易。
或者,您可以使用GSON [https://code.google.com/p/google-gson/],这些空字段将被自动删除。
SampleDTO.java
public class SampleDTO {
String username;
String email;
String password;
String birthday;
String coinsPackage;
String coins;
String transactionId;
boolean isLoggedIn;
// getters/setters
}
Test.java
import com.google.gson.Gson;
public class Test {
public static void main(String[] args) {
SampleDTO objSampleDTO = new SampleDTO();
Gson objGson = new Gson();
System.out.println(objGson.toJson(objSampleDTO));
}
}
OUTPUT:
{"isLoggedIn":false}
我用gson-2.2.4
如果您要从序列化中排除布尔类型,则下面的代码可能会有所帮助:
@JsonInclude(JsonInclude.Include.NON_ABSENT)
与现有答案相同