#JsonInclude(JsonInclude.Include.NON_DEFAULT)
I have a nested class structure as follows:
public class A{
String z;
String y;
float p;
List<B> b;
public static class B{
String x;
String w;
float q;
List<C> c;
public static class C{
String v;
String u;
float r;
}
}
}
I have another class as follows:
public class D{
List<B> b;
}
In my use case, I am returning class D as part of an API call. String x(in class B) and String v(in class C) will always be non-null. But String w and String u may or may not be null. I want to exclude null fields and default fields ( like 0.0 for float q and float r) from my response and therefore want to use #JsonInclude(JsonInclude.Include.NON_DEFAULT). But I don't want this to happen for all use cases, but only for my use case, i.e. only for class D? Is the following an effective way of achieving it?
#JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class D{
List<B> b;
}
Will the above way work on the inner classes as well? Please feel free to suggest another method because I'm unable to think of one.
I have got the following scenario in which I got four classes autogenerated (in a JAR):
Class A{
B bEl = ...;
}
Class B{
C cEl = ...;
}
Class C{
D dEl = ...;
}
Class E{
E eEl=...;
}
Setting up those objects it is quite painful and error prone. Therefore, I was wondering if there is a better way to automatically construct a builder. I am aware of Lombok but I cannot edit that code and I cannot add the #Builder annotation.
Any recommendation?
If you are not allowed to change existing classes you can extend them:
public class Existing {
String a;
String b;
public Test(String a, String b) {
this.a = a;
this.b = b;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
public class ExistingBuilder extends Existing {
#Builder
public ExistingBuilder(String a, String b) {
super(a, b);
// in case super class doesn't have all arguments constructor just call setters
// setA(a);
// setB(b);
}
}
So as you can see it's doable, but super class should have getters/setters or all args constructor.
I have two classes : class A , class B
class A{
private int F1;
private String F2;
}
class B{
private int F3;
private String F4;
private String F5;
}
I want a JSON like this:
{
"F1": 123
"F2": "ABC"
"F3": 456
"F4": "CDE"
"F5": "FGH"
}
I am using springboot which creates JSON as soon as I return object from #RestController. How can I achieve the above json using these two classes.
Note :
1.) I already know that by using class A extends B , I can achieve
this but I am looking for some spring based method to achieve this
2.) Using #Embeddable in class B & then creating reference in Class A creates
additional tag B in JSON as shown :
{
"F1": 123
"F2": "ABC"
b: {
"F3": 456
"F4": "CDE"
"F5": "FGH"
}
}
How about using jackson #JsonUnwrapped?
http://fasterxml.github.io/jackson-annotations/javadoc/2.0.0/com/fasterxml/jackson/annotation/JsonUnwrapped.html
public class A{
#JsonUnwrapped
private B b;
public User getB() ...
}
Create a delegating class AB:
public final class AB {
private final A a;
private final B b;
public AB(A a, B b) {
this.a = a;
this.b = b;
}
// Delegation methods to A
public int getF1() { return this.a.getF1(); }
public String getF2() { return this.a.getF2(); }
// Delegation methods to B
public int getF3() { return this.b.getF3(); }
public String getF4() { return this.b.getF4(); }
public String getF5() { return this.b.getF5(); }
}
I have a base class with two derived classes which all seem to use the same enum.
I want to use the enum at the base class, but change the assigned value depending on the instance of the derived class used.
How do I do this?
The Base class:
public class Base {
private MyEnum data = MyEnum.Z;
public Base() {
}
public void baseMethod() {
System.out.println("base data:? "+MyEnum.X);
data = MyEnum.Y;
data.showVal();
System.out.println("base value:? "+data);
}
//enum yet to be added
protected enum MyEnum {
X(0,2),
Y(1,3),
Z(4,5);
private int a,b;
MyEnum(int x, int y) {
a=x;
b=y;
}
public void showVal() {
System.out.println("a="+a+",b="+b);
}
}
}
The two derived classes:
public class A extends Base {
private MyEnum data = MyEnum.Z;
public A () {
}
public void firstMethod() {
System.out.println("A's DATA: "+MyEnum.X);
data = MyEnum.Y;
data.showVal();
System.out.println("A's value: "+data);
baseMethod();
}
protected enum MyEnum {
//values are different
X(10,11),
Y(12,13),
Z(14,15);
private int a,b;
MyEnum(int x, int y) {
a=x;
b=y;
}
public void showVal() {
System.out.println("a="+a+",b="+b);
}
}
}
public class B extends Base {
private MyEnum data = MyEnum.Z;
public B() {
}
public void secondMethod() {
System.out.println("B'S DATA: "+MyEnum.X);
data = MyEnum.Y;
data.showVal();
System.out.println("B's value: "+data);
baseMethod();
}
protected enum MyEnum {
//values are different
X(20,21),
Y(22,23),
Z(24,25);
private int a,b;
MyEnum(int x, int y) {
a=x;
b=y;
}
public void showVal() {
System.out.println("a="+a+",b="+b);
}
}
}
Please help.
Enums are basically final classes that you can't extend. You can implement an interface in an enum, but you cannot extend an enum to change one of its methods or the concrete values of the enum (the pair of integers you're referring to).
If you want to keep using enums, a solution to consider is to have a single MyEnum enum with X, Y, Z and to add a showVal(MyEnum value) method in the objects Base, A and B. The showVal method would simply associate the correct pair of integers for all your enum values (X, Y and Z).
Here is the logic for this approach:
MyEnum.java
public enum MyEnum{
X,Y,Z
}
Main.java
public class Main{
public static void main(String []args){
MyEnum value = MyEnum.X;
System.out.println("With Base:");
Base base = new Base();
System.out.println(base.showVal(value));//prints "a=0,b=2"
System.out.println("With A:");
A a = new A();
System.out.println(a.showVal(value)); //prints "a=10,b=11"
System.out.println("With B:");
B b = new B();
System.out.println(b.showVal(value)); //prints "a=20,b=21"
}
}
Base.java
public class Base{
public Base(){
//Do something...
}
public String showVal(MyEnum value){
switch(value){
case MyEnum.X:
return "a=0,b=2";
case MyEnum.Y:
return "a=1,b=3";
case MyEnum.Z:
return "a=4,b=5";
}
}
}
A.java
public class A extends Base{
public A(){
//Do something...
}
#Override
public String showVal(MyEnum value){
switch(value){
case MyEnum.X:
return "a=10,b=11";
case MyEnum.Y:
return "a=12,b=13";
case MyEnum.Z:
return "a=14,b=15";
}
}
}
B.java
public class B extends Base{
public B(){
//Do something...
}
#Override
public String showVal(MyEnum value){
switch(value){
case MyEnum.X:
return "a=20,b=21";
case MyEnum.Y:
return "a=22,b=23";
case MyEnum.Z:
return "a=24,b=25";
}
}
}
If you don't mind changing your structure, use an object to store a state representing X, Y or Z. You will be able to extend that parent object and give whatever par of integers you want in the child objects.
I do agree with #cydrickt, below there is a possible solution, changing the structure of your MyEnum.
I created a simple interface called IMyEnum which has a method to create a Pair of values:
public interface IMyEnum {
void showVal();
Pair getPair();
}
public class Pair {
private final int a;
private final int b;
public Pair(int a, int b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public int getB() {
return b;
}
}
All MyEnum classes implement the IMyEnum interface and each one of the enum constants override the getPair method, returning the appropriate values for a and b. I also made the data attribute of the Base class to be protected and refers to the IMyEnum type. Here is an example of the Base class after this refactoring:
public class Base {
protected IMyEnum data = MyEnum.Z;
public Base() {
}
public void baseMethod() {
System.out.println("base data:? " + MyEnum.X);
data = MyEnum.Y;
data.showVal();
System.out.println("base value:? " + data);
}
// enum yet to be added
protected enum MyEnum implements IMyEnum {
X(0, 2) {
#Override
public Pair getPair() {
return new Pair(X.a, X.b);
}
},
Y(1, 3) {
#Override
public Pair getPair() {
return new Pair(Y.a, Y.b);
}
},
Z(4, 5) {
#Override
public Pair getPair() {
return new Pair(Z.a, Z.b);
}
};
private int a, b;
MyEnum(int x, int y) {
a = x;
b = y;
}
#Override
public void showVal() {
System.out.println("a=" + a + ",b=" + b);
}
}
}
The other two classes A and B are similar to the Base class, its MyEnum class have to implement the IMyEnum interface and each X, Y and Z constants override the getPair method.
I have a Jaxb object that has an object tree 3 deep. I have created a seperate object that mirrors this Jaxb object. I am using the builder pattern to copy values from Jaxb to the bean. The issue is, when building A, I require an instance of B. But, the verion of B that the builder requires is different from the Jaxb version of B -the 'source'.
How do I build A?
public class A {
private B b;
public void setB(B b) {
this.b = b;
}
public static class ABuilder {
private B b;
public ABuilder withB(B b) {
this.b = b;
return this;
}
A build() {
A a = new A();
a.setB(b);
return a;
}
}
}
class B {
private C c;
private String name;
}
class C {
private int count;
}
class myMain {
com.myJaxb.B jaxbB;
A myA = new A.ABuilder().withB(jaxbB).build(); //error - withB doesnt take jaxb B
}