A simple plugin for converting POJO to JSON in IntelliJ IDEA
- Support any type you can think of in Java.
- Support Java17 and last
- Support Java14 Records JEP-359
- Partial support Jackson and Fastjson annotations.
- Support conversion
- Inner Class
- Global Variable
- Local Variable
- Constructor Parameter
- Method Parameter
- Java - full support
- Kotlin - full support
-
Note that the position of the cursor can affect the result!
-
Open class file > Move cursor to Class/Variable/Parameter > Right click > Copy JSON > JSON result will copy to clipboard
-
Open class file > Move cursor to Class/Variable/Parameter > Alt + Insert > Copy JSON > JSON result will copy to clipboard
-
Project view select a class file > Right click > Copy JSON > JSON result will copy to clipboard
-
Project view select multiple files > Right click > Copy JSON > JSON result will generate to files in the Scratches folder
-
Install in IDEA:
- Preferences(Settings) > Plugins > Marketplace > Search"POJO to JSON" > Install
-
Manual Install:
- plugin -> Preferences(Settings) > Plugins > ⚙️ > Install plugin from disk... -> Select the plugin package and install(No need to unzip)
-
Why always report errors when use it?
This class reference level exceeds maximum limit or has nested references!
When the program throws this warning there are only two possibilities.
-
This class or parent class has nested references
eg:
public class A { private B b; public class B { private A a; } }
{ "b":{ "a":{ "b":{ "a":{ ...... } } } } }
or
public class A { private A a; }
{ "a":{ "a":{ "a":{ "a":{ ...... } } } } }
-
This class reference level > 200
eg:
public class A { private B _0; public class B { private C _1; public class C { private D _2; public class D { // _3 ..... _201.. } } } }
{ "_0": { "_1": { "_2": { "......_201":{} } } } }
Perhaps both will happen for entity but this entity are not suitable for JSON.
So you can try to serialize your POJO using Jackson to see what happens.
If no exception, you can submit a bug to this repository issues with your target class :)
-
-
But how to solve this problem?
You can try the following methods.
-
@JsonProperty and @JSONField
import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonProperty; public class User { @JsonProperty("name") private String username; @JSONField(name = "pass") private String password; }
paste result:
{ "name": "", "pass": "" }
-
@JsonIgnore or Javadoc tags JsonIgnore
import com.fasterxml.jackson.annotation.JsonIgnore; public class User { @JsonIgnore private String username; private String password; }
or when there is no jackson library
public class JsonIgnoreDocTestPOJO { /** * @JsonIgnore */ private String username; private String password; }
paste result:
{ "password": "" }
-
@JsonIgnoreProperties or Javadoc tags JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.List; public class User { private String username; @JsonIgnoreProperties({"users", "aaa", "bbb"}) private List<Role> roles; public class Role { private String roleName; private List<User> users; } }
or when there is no jackson library
import java.util.List; public class User { private String username; /** * @JsonIgnoreProperties users, aaa, bbb */ private List<Role> roles; public class Role { private String roleName; private List<User> users; } }
paste result:
{ "username": "", "roles": [ { "roleName": "" } ] }
You may encounter this problem during use.
This class reference level exceeds maximum limit or has nested references!
The above method can solve the nested reference problem well.
-
@JsonIgnoreType
import com.fasterxml.jackson.annotation.JsonIgnoreType; import java.util.List; public class User { private String username; private List<Role> roles; @JsonIgnoreType public class Role { private String roleName; private List<User> users; } }
paste result:
{ "username": "", "roles": [] }
What can SpEL expression do?
-
Configure meaningful test values.
-
Field-level control of convert results.
-
Customize any type you want to convert.
-
This is a default configuration. Normally no modification.
com.fasterxml.jackson.databind.JsonNode=#{#object.getValue()} com.fasterxml.jackson.databind.node.ArrayNode=#{#array.getValue()} com.fasterxml.jackson.databind.node.ObjectNode=#{#object.getValue()} java.lang.Boolean=#{#boolean.getValue()} java.lang.CharSequence=#{#field.getName() + '_' + #shortuuid.getValue()} java.lang.Character=#{'c'} java.lang.Double=#{#decimal.getValue()} java.lang.Float=#{#decimal.getValue()} java.lang.Number=#{#integer.getValue()} java.math.BigDecimal=#{#decimal.getValue()} java.time.LocalDate=#{#datetime.getValue('yyyy-MM-dd')} java.time.LocalDateTime=#{#datetime.getValue('yyyy-MM-dd HH:mm:ss')} java.time.LocalTime=#{#datetime.getValue('HH:mm:ss')} java.time.YearMonth=#{#datetime.getValue('yyyy-MM')} java.time.ZonedDateTime=#{#datetime.getValue()} java.time.temporal.Temporal=#{#temporal.getValue()} java.util.AbstractMap=#{#object.getValue()} java.util.Date=#{#datetime.getValue('yyyy-MM-dd HH:mm:ss')} java.util.Map=#{#object.getValue()} java.util.UUID=#{#uuid.getValue()}
-
If you want to ask where the previous option
Copy JSON and Random Values
went? Use the following configuration to achieve the previous effect.com.fasterxml.jackson.databind.JsonNode=#{#object.getValue()} com.fasterxml.jackson.databind.node.ArrayNode=#{#array.getValue()} com.fasterxml.jackson.databind.node.ObjectNode=#{#object.getValue()} java.lang.Boolean=#{#boolean.getRandomValue()} java.lang.CharSequence=#{#field.getName() + '_' + #shortuuid.getValue()} java.lang.Character=#{'c'} java.lang.Double=#{#decimal.getRandomValue()} java.lang.Float=#{#decimal.getRandomValue()} java.lang.Number=#{#integer.getRandomValue()} java.math.BigDecimal=#{#decimal.getRandomValue()} java.time.LocalDate=#{#datetime.getRandomValue('yyyy-MM-dd')} java.time.LocalDateTime=#{#datetime.getRandomValue('yyyy-MM-dd HH:mm:ss')} java.time.LocalTime=#{#datetime.getRandomValue('HH:mm:ss')} java.time.YearMonth=#{#datetime.getRandomValue('yyyy-MM')} java.time.ZonedDateTime=#{#datetime.getRandomValue()} java.time.temporal.Temporal=#{#temporal.getRandomValue()} java.util.AbstractMap=#{#object.getValue()} java.util.Date=#{#datetime.getRandomValue('yyyy-MM-dd HH:mm:ss')} java.util.Map=#{#object.getValue()} java.util.UUID=#{#uuid.getValue()}
Expression | Result Eg | |
---|---|---|
Camel Case(Default) | #{#field.getName()} or #{#field.getCamelCaseName()} |
testName |
Snake Case | #{#field.getSnakeCaseName()} |
test_name |
Kebab Case | #{#field.getKebabCaseName()} |
test-name |
Pascal Case | #{#field.getPascalCaseName()} |
TestName |
Snake Case Upper | #{#field.getSnakeCaseUpperName()} |
TEST_NAME |
-
Full compliance with SpEL expression standards.
-
Expressions need to be used only when operations or references are required. The expression must start with
#{
and end with}
# result {"test":"ABCD"} com.example.TestClass=ABCD
# result {"test":"ABCD_4_732f65b6b9cf"} com.example.TestClass=ABCD#{"_" + 2+2 + "_" + #shortuuid.getValue()}
-
The plugin has some built-in shortcut references.Note that not all references support
getRandomValue()
Ref | Expression | Result Eg | Support getRandomValue() |
---|---|---|---|
#boolean |
#{#boolean.getValue()} |
false | |
#array |
#{#array.getValue()} |
[] | N |
#object |
#{#object.getValue()} |
{} | N |
#decimal |
#{#decimal.getValue()} |
0.00 | |
#integer |
#{#integer.getValue()} |
0 | |
#localdatetime |
#{#localdatetime.getValue()} |
2023-09-14 15:04:52 | |
#localdate |
#{#localdate.getValue()} |
2023-09-14 | |
#localtime |
#{#localtime.getValue()} |
15:04:52 | |
#yearmonth |
#{#yearmonth.getValue()} |
2023-09 | |
#temporal |
#{#temporal.getValue()} |
1694675092600 | |
#zoneddatetime |
#{#zoneddatetime.getValue()} |
2023-09-14T15:04:52.601+08:00 | |
#uuid |
#{#uuid.getValue()} |
679e70fa-d24b-4726-ab87-2de620333f20 | N |
#shortuuid |
#{#shortuuid.getValue()} |
732f65b6b9cf | N |
#datetime |
#{#datetime.getValue()} |
2023-09-14T15:04:52.601+08:00 |
-
Custom Date Format
java.time.YearMonth=#{#datetime.getValue('yyyy-MM')}
or need random values
java.time.YearMonth=#{#datetime.getRandomValue('yyyy-MM')}
-
Custom Number types
# Get a random number between 0 and 100, retaining 2 decimal places. java.math.BigDecimal=#{#decimal.getRandomValue(0,100,2)}
# Get a random number between 0 and 100, retaining 2 decimal places. java.math.BigDecimal=#{#decimal.getRandomValue(2)}
-
Custom String type
java.lang.CharSequence=#{#field.getName() + '_' + #shortuuid.getValue()}
or
java.lang.String=#{#field.getName() + '_' + #shortuuid.getValue()}
The
#field
reference is quite special and can be simply understood as each field in the Class.It actually points to a PsiVariable instance. -
You will find that this configuration has an extends relationship.So you can define the expression of the parent class, and the sub-class will also benefit.
com.example.ParentClass=#{#field.getName() + '_' + #shortuuid.getValue()}
class SubClass extends ParentClass { } public class Test { private SubClass subClass; }
json result:
{ "subClass": "subClass_4c672dc197e3" }
-
Some special cases, SpEL expressions cannot be adapted.
-
You cannot create custom classes outside of Java Base package because plugins cannot reflect instances of custom classes.
You can
java.lang.Number=#{new java.math.BigDecimal(6)}
You can't
java.lang.Number=#{new com.example.BigDecimal(6)}
-
The test found that the first situation will cause problems in Kotlin.
Eg
java.lang.Number=#{#integer.getRandomValue}
But recommended this
java.lang.Number=#{#integer.getRandomValue()}
-
When incorrect configuration causes the plugin to fail to run properly, you can clear the configuration and save it, and the plugin will initialize the default configuration.
-
Ideas and partial realization from linsage