简体   繁体   中英

Spring @RequestBody mapping issue - how to see unmapped values?

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

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
}

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM