1

I already have a JSON string (automatically treated as JsonNode), with many string fields. All values for any string field are already escaped if there are quotes or other characters in it. Whether I deserialize/transform the JSON / JsonNode, every string in the POJO is unescaped. After serialization of the POJO all string values are escaped again. If I escape any string value by hand, all values are double escaped after serialization.

Question: Is there a way via mapper settings or class/property annotations to keep the input as it is without losing the backslashes after deserialization?

Here is a pseudo example of what I need / what I'm doing:

A request comes in:

{
    "dateFrom": "2005-01-01",
    "dateTo": "2016-07-22",
    "queryString": "cheese steak jimmys \"cheesesteakjimmys\""
}

After this I want to query some data but this would lead to database errors, because via request.getQueryString() I get:

"cheese steak jimmys "cheesesteakjimmys""

If I escape it in setQueryString() at deserialization this would lead to the below result after writing it back:

{
    "timestamp": 144412412515,
    "body": {
        "dateFrom": "2005-01-01",
        "dateTo": "2016-07-22",
        "queryString": "cheese steak jimmys \\\"cheesesteakjimmys\\\""
    }
}

The wanted output in getQueryString():

"cheese steak jimmys \"cheesesteakjimmys\""

Jackson-Version: 2.8.0

Thank you in advance, -Y-

UPDATE

//the incoming request POJO
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AbstractRequest {
    private String queryString;
    private String dateFrom;
    private String dateTo;

    public String getQueryString() {
        return queryString;
    }

    public void setQueryString(String queryString) {
        this.queryString = queryString;
    }

    public String getDateFrom() {
        return dateFrom;
    }

    public void setDateFrom(String dateFrom) {
        this.dateFrom = dateFrom;
    }

    public String getDateTo() {
        return dateTo;
    }

    public void setDateTo(String dateTo) {
        this.dateTo = dateTo;
    }
    //toString()
}

The persisted object with the body of the executed request:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class PersistedRequest {
    private long timestamp;
    private AbstractRequest body;

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public AbstractRequest getBody() {
        return body;
    }

    public void setBody(AbstractRequest body) {
        this.body = body;
    }
    //toString()
}

Parsing the initial request into POJO:

JsonNode body = request().body().asJson();
AbstractRequest request = null;
try {
    request= mapper.treeToValue(body, AbstractRequest.class);
} catch (Exception e) {
    Logger.error("Cannot Parse request", e);
}


//body.toString() gives this output
//{"datefrom":"2005-01-01","dateTo":"2016-07-22","queryString":"cheese steak jimmys \"cheesesteakjimmys\""}

request.toString() brings:

//AbstractRequest{queryString='cheese steak jimmys "cheesesteakjimmys"', dateFrom='2005-01-01', dateTo='2016-07-22'}
//NO backslashes anymore
//querying for some data via request.getQueryString() would now result in data base errors

Parsing the request back to persist it:

PersistedRequest persistedRequest = new PersistedRequest();
persistedRequest.setBody(request);
JsonNode persistedRequestAsNode = mapper.valueToTree(persistedRequest);
//persistedRequestAsNode.ToString() for brevity brings
//{"body":{"queryString":"cheese steak jimmys \"cheesesteakjimmys\""}}

//DAO.create(persistedRequestAsNode)
Yeti
  • 63
  • 7
  • Post the code where you are constructing a new json. – Murat Karagöz Jul 22 '16 at 11:50
  • @MuratK. I edited the question to provide more details – Yeti Jul 22 '16 at 13:50
  • It sounds like your reason for asking this question is that working with unescaped strings will "lead to database errors". That makes me think you're plugging the value from the JSON directly into an SQL string. Don't do that: prepared statements and [bind parameters](http://use-the-index-luke.com/sql/where-clause/bind-parameters) are easier and safer. Use `connection.prepareStatement(sql)` and `preparedStatement.setString(index, queryString)`. In your SQL string, write question marks in the spots where parameters like the `queryString` should go. – Wyzard Jul 22 '16 at 15:59
  • @Wyzard at first thank you for your reply. But I'm not using SQL, I use elasticsearch. Therefore I'm plugging the value into a query template which is already a kind of the technique you mentioned. I'm looking for a solution to get the value after deserialization as it is. In fact this killing of backslashes must be done by some settings in the mapper/json generator but I haven't found them so far. – Yeti Jul 23 '16 at 19:11
  • 2
    This works for me. Hope it helps you also https://stackoverflow.com/a/40972234/4141400 – Rashmi Ramanathan Jun 13 '17 at 06:59
  • did you found the solution eventually? Im facing the same problem now. – quit Nov 29 '19 at 15:08

0 Answers0