Reputation: 191
I'm using a Spring Controller to transform JSON to Java via the @RequestBody annotation. I'm debugging this but, as I've been through this before, I understand the JSON is not being mapped to my entity, but I'm very curious what the non mapped JSON is, from Java's perspective. Is there any way to make that visible in my Controller? Here's my controller method:
@PostMapping(path="/Add") // Map ONLY GET Requests
public @ResponseBody PurchaseRequestLineItem addNewPurchaseRequestLineItem (@RequestBody PurchaseRequestLineItem purchaseRequestLineItem) {
purchaseRequestLineItemRepository.save(purchaseRequestLineItem);
System.out.println("PurchaseRequestLineItem saved: "+purchaseRequestLineItem);
return purchaseRequestLineItem;
}
Here's my Entity:
package com.prs.business.purchaserequest;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name="purchaserequestlineitem")
public class PurchaseRequestLineItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
// @Column(name="purchaserequestid")
// private int purchaseRequestID;
@ManyToOne
@JoinColumn(name="PurchaseRequestID")
@JsonIgnore
private PurchaseRequest purchaseRequest;
private int productID;
private int quantity;
public PurchaseRequestLineItem() {
id = 0;
//purchaseRequestID = 0;
purchaseRequest = null;
productID = 0;
quantity = 0;
}
public PurchaseRequestLineItem(PurchaseRequest inPR, int inPdtID, int inQty) {
purchaseRequest = inPR;
productID = inPdtID;
quantity = inQty;
}
// public PurchaseRequestLineItem(int inPRID, int inPdtID, int inQty) {
// purchaseRequestID = inPRID;
// productID = inPdtID;
// quantity = inQty;
// }
//
public PurchaseRequestLineItem(int inID, PurchaseRequest inPR, int inPdtID, int inQty) {
id = inID;
purchaseRequest = inPR;
productID = inPdtID;
quantity = inQty;
}
// public PurchaseRequestLineItem(int inID, int inPRID, int inPdtID, int inQty) {
// id = inID;
// purchaseRequestID = inPRID;
// productID = inPdtID;
// quantity = inQty;
// }
//
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// public int getPurchaseRequestID() {
// return purchaseRequestID;
// }
//
// public void setPurchaseRequestID(int purchaseRequestID) {
// this.purchaseRequestID = purchaseRequestID;
// }
//
public PurchaseRequest getPurchaseRequest() {
return purchaseRequest;
}
public void setPurchaseRequest(PurchaseRequest purchaseRequest) {
this.purchaseRequest = purchaseRequest;
}
public int getProductID() {
return productID;
}
public void setProductID(int productID) {
this.productID = productID;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
@Override
public String toString() {
return "\npurchaseRequestLineItem [id=" + id + ", purchaseRequest=" + purchaseRequest + ", productID="
+ productID + ", quantity=" + quantity + "]";
}
}
And my line from my properties file: spring.jackson.property-naming-strategy=UPPER_CAMEL_CASE
Upvotes: 1
Views: 3165
Reputation: 38300
Assuming that you use Jackson JSON mapping,
as noted by @gtosto,
accept the @RequestBody
as a String and perform the conversion from String to JSON yourself.
Do that (the translation thing) using an ObjectMapper.
Here is a simple method for that:
public <Type> Type getInputJson(
final String trackId,
final Class<Type> inputJsonClass,
final String inputJsonString)
{
Type returnValue;
try
{
returnValue = objectMapper.readValue(
inputJsonString,
inputJsonClass);
}
catch (IOException exception)
{
logger.warn(
"exception while converting inputJson. inputJsonClass.name: {}, inputJsonString: {}",
inputJsonClass.getName(),
inputJsonString);
returnValue = null;
}
return returnValue;
}
Edit removing my junk (CoreUtil). Also, I use logback, so my log strings might not match yours.
A second option is to accept an @RequestBody
parameter like you are currently doing and add a WebRequest
or HttpServletRequest
parameter.
These give you access to the entire request (including the request body).
Note Using the ObjectMapper
does not make the unmapped stuff available to you, it just does the json -> object mapping. You need to examine the inputJsonString
to find the unmapped values.
I use the following 3 jackson dependencies:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
and the following property:
<jackson.version>2.2.3</jackson.version>
Upvotes: 0
Reputation: 1341
You can just use String
to see request body as is
@PostMapping(path="/Add") // Map ONLY GET Requests
public @ResponseBody PurchaseRequestLineItem addNewPurchaseRequestLineItem (@RequestBody String json) {
// do whatever you want
}
Upvotes: 4