#JsonValue and #ApiModelProperty conflicts - java

in my project I am using Swagger to document REST API. I have simple value object which I want to document.
public class MyClass {
#JsonValue
private String myField;
public String getMyField() {
return myField;
}
}
Unfortunately, when I am adding swagger annotations and then see created documentation, there is no information about this VO.
Class with swagger annotations below:
#ApiModel(value = "MyClass ", description = "represents my class")
public class MyClass {
#JsonValue
#ApiModelProperty(value = "name", dataType = "String", example = "my field")
private String myField;
public String getMyField() {
return myField;
}
}
Wanted to check this issue I temporally removed #JsonValue annotation and documentation was created properly, annotation #ApiModelProperty worked.
I cannot remove #JsonValue annotation permanently.
Does anybody know the solution how can I force those two tools to cooperate?

Related

Spring Boot parse JSON data to Java Class with different field names

I am new to Spring Boot and I am trying to figure out how to parse json data. I see a lot of tutorials on how to map json string object to an annotated Java class and using and object mapper, like this:
json:
{
"UUID": "xyz",
"name": "some name"
}
public class MyClass{
#JsonProperty
private UUID id;
#JsonProperty
private String name;
#JsonAnyGetter
public UUID getId() {
return this.id;
}
#JsonAnySetter
public void setId(UUID id) {
this.id = id;
}
#JsonAnyGetter
public String getName() {
return this.name;
}
#JsonAnySetter
public void setName(String name) {
this.name = name;
}
}
ObjectMapper objectMapper = new ObjectMapper();
MyClass customer = objectMapper.readValue(jsonString, MyClass.class);
The problem is that the system I am getting the json string from does not match the class naming conventions we use (and I cannot change either one). So, instead of having the example json string above, it might look like this:
{
"randomdstring-fieldId": "xyz",
"anotherrandomstring-name": "some name"
}
This use case only has two fields, but my use case has a larger payload. Is there a way to either map the field names from the json object to the field names in the Java class or is there a way to just parse the json string as a key value pair (so that I can just manually add the fields to my Java object)?
In Jackson with #JsonProperty you can customize the field name with it's annotation parameter value
Therefore, you just have to annotate the entity fields with the #JsonProperty annotation and provide a custom JSON property name, like this:
public class MyClass{
#JsonProperty("original_field_name_in_json")
private UUID id;
...
The #JsonProperty will do it for you:
#JsonProperty("name_in_json")
private Long value;

SDN6 - Projection interfaces with Property Mapping

I am using spring data neo4j 6.1.3 and following is my use case code snippets
Domain Entity
#Data
#Node("DATspace")
public class DatSpace {
#Id #GeneratedValue
private Long neoId;
#Property("SUPtitle")
private String title;
private String SUPid;
}
Test class
#SpringBootTest
#EnableNeo4jRepositories(basePackages = "com.rahal.marvel")
public class ProjectionTest {
#Autowired
private Neo4jTemplate neo4jTemplate;
interface DATspaceProjection {
String getTitle();
String getSUPid();
}
#Test
public void test_projection(){
DatSpace d = neo4jTemplate.findOne("MATCH (s:DATspace {SUPid: $id}) RETURN s", Collections.singletonMap("id", "SPC_ML7"), DatSpace.class).get();
d.setTitle("title modified");
d.setSUPid("SUPid modified");
DATspaceProjection p = neo4jTemplate.saveAs(d, DATspaceProjection.class);
}
}
Ideally above saveAs function should modify both DATspace.SUPtitle and DATspace.SUPid. However it only modify SUPid but not SUPtitle. I presume it is due to property mapping (#Property) . Is this a bug or are there any workaround?
The provided #Property annotation does only have an impact on the annotated property (title) itself.
There is no knowledge right now that goes from the getTitle() method in the projection to the annotated title field in the domain class.
To be safe when modifying this use the explicit property name:
interface DATspaceProjection {
String getSUPtitle();
String getSUPid();
}
I created an issue for improvement https://github.com/spring-projects/spring-data-neo4j/issues/2371

Create #ToLowerCase annotation to convert String value to lower case

We have SpringBoot application.
For our pojo's we want to create a custom #ToLowerCase annotation which converts the field variable value to lower case.
Eg:
#Data
Employee {
private String name;
#ToLowerCase
private String emailId;
private String gender;
private String phoneNumber;
}
So my custom #ToLowerCase annotation should convert emailId to lower case.
We want to use this annotation on all kind of Pojos, whether it is rest request pojo or JPA entity pojo.
I have gone through posts on many forums but didn't get any appropriate solution for same.
Is it possible to create such annotation in Spring Boot? If yes then how?
Kindly help
Thanks
Create a custom converter: ToLowerCaseConverter.
public class ToLowerCaseConverter extends StdConverter<String, String> {
#Override
public String convert(String value) {
if (value == null){
return null;
}
return value.toLowerCase();
}
}
After create a new annotation: ToLowerCase. It works for both incoming and outgoing Strings (#JsonDeserialize/#JsonSerialize).
#Retention(RetentionPolicy.RUNTIME)
#JacksonAnnotationsInside
#JsonSerialize(converter = ToLowerCaseConverter.class)
#JsonDeserialize(converter = ToLowerCaseConverter.class)
public #interface ToLowerCase {
}
Finally, your example will work as intended:
#Data
Employee {
#ToLowerCase
private String emailId;
}

How to hide fields with a condition in RESTful WS?

I have a class called Report that I need to share using RESTful WS.
once in full with all its attributes
once in only a reduced version
Normally I'd use something like #XmlTransient to hide the fields, but this would prevent the full version from working.
Is there any way to set a condition or to kind of pre-filter fields just before the output so that it doesn't affect other uses of the same class?
My Report class looks like this:
public class Report {
private String reportId;
private String title;
private String content;
private Date created;
private Date modified;
...
}
The RESTful sharing for the full Report looks like this:
#GET
#Path("/{reportId}")
public Report getReport(#PathParam("reportId") String reportId) {
return Mock.getReport(reportId);
}
The full output I need looks like this:
{
"reportId": "d83badf3",
"title": "The tales of lamaru",
"content": "When once the great Imgur started his journey...",
"created": 1519672434866,
"modified": 1519672434866
}
The short output I need should look like this:
{
"reportId": "d83badf3",
"title": "The tales of lamaru"
}
What is necessary to achieve this?
Why don't you use Inheritance?
Parent
public class Report {
private String reportId;
private String title;
}
Child
public class FullReport extends Report{
private String content;
private Date createdp;
private Date modified;
}
When you need full report set return type as FullReport otherwise Report
Jackson has two different annotations to use when you want to exclude some class members from the JSON serialization and deserialization processes. These two annotations are #JsonIgnore and #JsonIgnoreProperties.
#JsonIgnoreProperties is an annotation at the class level and it expects that the properties to be excluded would be explicitly indicated in the form of a list of strings.
#JsonIgnore instead is a member-level or method-level annotation, which expects that the properties to be excluded are marked one by one.
try this.
public class Report {
private String reportId;
private String title;
#JsonIgnore
private String content;
#JsonIgnore
private Date created;
#JsonIgnore
private Date modified;
...
}

jackson generating an unexpected "new" field

I'm using spring rest and jackson to generate json. For the class country
public class Country extends AbstractPersistable<Long> {
private String name;
private String code2;
private String code3;
public Country() {
}
public Country(String name, String code2, String code3) {
...
}
...
}
I get, for example,
{
"id" : 1,
"name" : "Afghanistan",
"code2" : "AF",
"code3" : "AFG",
**"new" : false**
}
For some classes I get an unexpected "new" field always set to false. I suspect it has something to do with the parametrized constructor, but it's just a guess. Ideas?
The class AbstractPersistable has a public method called isNew specified by the interface Persistable (the doc here).
You will have to ignore such property if you don't want it in your JSON, for example, using the annotation JsonIgnoreProperties in your class.

Categories