Spring MVC - date issue - json

Backend Spring MVC and Hibernate. Front end Angularjs. The database I am using is DB2.
Problem: the data field in my JSON object is returning under the form of a random integer ("startDate":1450828800000). The actual date in the DB is "2015-12-23".
The data type for this column in the db is set to DATE.
My code:
#Entity
#Table(name = "PURCHASEORDER",schema = "POTOOL")
public class PurchaseOrder {
#Id
#GeneratedValue
private int id;
private Date startDate;
//rest of the code, including getter and setters

What you see in your JSON response is not a random integer, rather your DB value converted to milliseconds. You can annotate your Date with the following annotation to have the same representation as inside a DB
#JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
private Date startDate;
The annotations belong to jackson-annotation.jar if you're using maven you can add the following dependency and it will pull the annotations jar transitively
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1</version>
</dependency>
if you're not using maven you can still download the jars from maven repo, or find the equivalent conf for your build, hope it helps

It turns out that I can format the date with Angularjs like this: {{po.startDate |date:"yyyy-MM-dd" }}
Still confused why the on the JSON response the date is not converted...

Related

Validating Post Json Data Spring Boot

Controller
#RequestMapping(value="/create", method=RequestMethod.POST, consumes={"application/json"})
public Alien addDetails(#RequestBody Alien alien){
return repo.save(alien);
}
Alien.java
#Entity
public class Alien{
#Id
private int id;
private String name;
private String planet;
Getter and setter
Now I want to validate the post json data before saving it to the database.
If any of the field is empty then the controller should return an error.
For example
{"id": 1, "name": "Alien1", "planet":"Mars" }
This is acceptable json data
But if there is any field is missing such as
{"name": "Alien1", "planet":"Mars" }
Then the controller should return an error and not creating the instance of Alien
I tried with #Valid #NotNull still the controller creates an empty instance of Alien and save to the database.
First of all, you should add spring boot validation dependency into your pom.xml :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
And then add annotations like #NotBlank or #NotEmpty to verify if a value is assigned to that field or not. Those annotations should be on the top of your entity's attributes which you want to validate them.For example:
public class Alien{
#NotBlank(message="Name is mandatory")
private String name;
}
Finally, add #Valid annotation into your controller method like:
public Alien addDetails(#Valid #RequestBody Alien alien){
return repo.save(alien);
}
You should add #Validated annotation to your controller to make #Valid annotation do the work. You should also annotate fields in your Entity with constraints.
I.e., name could be #NotBlank.
And yes, make sure that you have imported:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Edit:
In Controller, you should not accept Entity as a body. Instead, you should create a DTO object and then map it to the Entity in the service. You should also put validation constraints on the DTO!

How to parameterize .json file in rest assured?

I am new to rest assured automation framework, so need help. I have to automate a simple API wherein I send the request in body.
given().log().all().contentType("application/json").body(payload).when().log().all().post("THE
POST URL").then().log().all().assertThat().statusCode(200);
I have to read the request from json file, and I am able to read the request from the .json file successfully. But I want to parameterize the values, and unable to understand on how to parameterize the file. Following is the sample .json file:
{
"id" : 5,
"name" : "Harry"
}
I do not want to hardcode the values of id and name here, but instead parameterize them using data providers or any other method. Any pointers on the same would be helpful.
A good practice for API testing using Rest-Assured is POJO approach. It helps you avoid manipulating json file (one kind of hardcode)
Step 1: You define a POJO
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Person {
private int id;
private String name;
}
I use lombok for generating verbose code.
Step 2: Create Data-provider method
#DataProvider(name = "create")
public Iterator<Person> createData() {
Person p1 = new Person(1, "Json");
Person p2 = new Person(2, "James");
Person p3 = new Person(3, "Harry");
return Arrays.asList(p1,p2,p3).iterator();
}
Step 3: Write test
#Test(dataProvider = "create" )
void test1(Person person) {
given().log().all().contentType(JSON)
.body(person)
.post("YOUR_URL")
.then().log().all().assertThat().statusCode(200);
}
You need to add 2 lib into your project classpath to make above code work.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>

Why is my converted column marked by JpaAttributeTypeInspection with the error message "'Basic' attribute type should not be a map"?

I was trying to store some JSON as a string in a column via JPA and Spring and was following a baeldung tutorial. My code like this:
#Column
#Convert(converter = MyEntityExtentionConverter.class)
private Map<String, Object> myEntityExtention;
MyEntityExtentionConverter is an implementation of javax.persistence.AttributeConverter<Map<String, Object>, String> that converts the string back and forth using the Jackson ObjectMapper.
According to mentioned tutorial this should have been it, however now I get an Error that
'Basic' attribute type should not be a map
Theoretically I could disable it by adding #SuppressWarnings("JpaAttributeTypeInspection") to the annotations, but that feels like ignoring rather than solving the error. What am I doing wrong here?
You have to annotate prop "myEntityExtention" with #Type but is not possible to add both #Type and #Convert..
as you can see in this tutorial you have to define the json type on the top of your entity:
#Entity
#Table(name = "some_table_name")
#TypeDef(name = "json", typeClass = JsonStringType.class)
public class CustomEntity {
then add #Type annotation instead #Convert:
#Type( type = "json" )
private Map<String, Object> myEntityExtention;
be sure to add all the right dependencies/versions.
I.E. i'm using hibernate 5.4 so my dependencies are:
<!-- Hibernate ORM core version 5.4.21.Final (inherited from spring-boot 2.3.4)-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<!--for hibernate >= 5.2-->
<version>2.10.2</version>
</dependency>
</dependencies>
Look like this is an issue from IntelliJ IDEA:
https://youtrack.jetbrains.com/issue/IDEA-270687
We can use workaround by this way:
Using the #SuppressWarnings("JpaAttributeTypeInspection") annotation removes the warning.
That field is not meant to be persisted. Remove the #Column annotation and use #Transient.
You are supposed to persist it as a JSON which will be done in the customerAttributeJSON, when reading from the database the customerAttributes will be populated and you can use it with DTOs.
#Entity
#Table(name = "Customers")
public class Customer {
#Id
private int id;
private String firstName;
private String lastName;
private String customerAttributeJSON;
#Transient
#Convert(converter = HashMapConverter.class)
private Map<String, Object> customerAttributes;
}

Rest Api Data Representation

I hava an Spring Boot Rest Api
#RestController
public class BookController {
#Autowired
private BookRepository bookRepo;
#GetMapping(value = "/library/", produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public List<Book> index(){
Iterable<Book> bookIterable = bookRepo.findAll();
List<Book> bookList = new ArrayList<>();
bookIterable.forEach(a->bookList.add(a));
return bookList;
}
My Homework is to add an additonal data representation so that when i put in the request i should can choose between which data representation i won't XML or JSON
Problem is
I get even json how can i change between XML and Json when i do a get Request to the Endpoint
To solve your problem you need to use the Accept header. more details
The Content Type header indicates the type of data that you pass in the request. more details
You need to make a request with the header, if you want to send and receive xml:
Accept: application/xml;
Content-Type: application/xml;
usefull link
Ok now i found it my self what you need to know in order to use an XML output is first add
to the pom.xml file following dependencies: Jackson XML Dataformat
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
Then i just have to Add Jackson Annotations to my Entity Class
#Entity
#JacksonXmlRootElement
public class Book {
public Book() {
}
#JacksonXmlProperty(isAttribute = true)
#Id
#GeneratedValue
private Integer id;
#JacksonXmlProperty(isAttribute = true)
private String title;
#JacksonXmlProperty(isAttribute = true)
private Integer numberOfCopies;
Thats it then i can Make a request with the Accept Header value application/xml

How to configure jackson in spring dispatcher servlet?

I want to send json data to controller in spring.How to configure jackson in dispatcher servlet and which jackson files to add in build path/lib?
You need to add the Jackson dependency first:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.7.1</version> //your version//
</dependency>
You must add #ResponseBody statement in your code as well. For example:
public class JSONController {
#RequestMapping(value="{name}", method = RequestMethod.GET)
public #ResponseBody Shop getShopInJSON(#PathVariable String name) {
Shop shop = new Shop();
shop.setName(name);
shop.setStaffName(new String[]{"mkyong1", "mkyong2"});
return shop;
}
}
Also, add < mvc:annotation-driven /> into your Spring XML configuration file.
You can find a full example of Jackson and Spring in this link.