FasterXML / jackson-databind

General data-binding package for Jackson (2.x): works on streaming API (core) implementation(s)
Apache License 2.0
3.51k stars 1.37k forks source link

How to escape double quotes contained in a JSON value? #4511

Closed miridih-jshwang closed 4 months ago

miridih-jshwang commented 4 months ago

Is your feature request related to a problem? Please describe.

Hello.

With the Claude3 response, we got the following JSON string value. However, the value contains an unescaped ", which results in the following error. Is there any way to escape double quotes contained in a value?

Thank you.

Version

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.LinkedHashMap;
import java.util.Map;

class JsonParserTest {
    public static void main(String[] args) {
        try {
            String response = "{\"dynamicKey1\": \"dynamicValue1 \"with\" \"inner\" double \"quotes\" data\",\"dynamicKey2\": \"dynamicValue2 \"1999\"\"}";
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, String> map = objectMapper.readValue(response, new TypeReference<LinkedHashMap<String, String>>() {
            });

            for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println("entry.getKey() = " + entry.getKey());
                System.out.println("entry.getValue() = " + entry.getValue());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('w' (code 119)): was expecting comma to separate Object entries at [Source: (String)"{"dynamicKey1": "dynamicValue1 "with" "inner" double "quotes" data","dynamicKey2": "dynamicValue2 "1999""}"; line: 1, column: 34]

Describe the solution you'd like

We want to escape the unescaped response via ObjectMapper and convert it to a map like this.

String response = "{\"dynamicKey1\": \"dynamicValue1 \"with\" \"inner\" double \"quotes\" data\",\"dynamicKey2\": \"dynamicValue2 \"1999\"\"}"
Map<String, String> map = new LinkedHashMap<>();
map.put("dynamicKey1", "dynamicValue1 \"with\" \"inner\" double \"quotes\" data");
map.put("dynamicKey2", "dynamicValue2 \"1999\"");

Usage example

No response

Additional context

No response

JooHyukKim commented 4 months ago

This issue seems more like usage question, could you convert this into Github DIscussion?

yihtserns commented 4 months ago

(Actually it seems more like a Java question...)

miridih-jshwang commented 4 months ago

(Actually it seems more like a Java question...)

The intent of my question was to know if an ObjectMapper can handle unescaped JSON values by escaping them, like json_repair in python.

I think it may seem like a java issue due to the lack of explanation. Thanks for your comment.

cowtowncoder commented 4 months ago

That is invalid content -- technically not JSON, nor "fixable" in an easy way -- and should not work as-is. But perhaps there could be some other package that tries to "fix" broken JSON-like content? (like json_repair mentioned)

At any rate, Jackson has no options to try to handle such broken content.

ps. FWTW, I would suggest spending more effort fixing broken content than trying to figure out work-arounds. This is a clear case of something else being broken and making systems that work with such content just keeps broken things in circulation.

yihtserns commented 4 months ago

Teach the AI to escape the double quotes! 🤭

cowtowncoder commented 4 months ago

@yihtserns I don't doubt it could work, but is REALLY expensive thing to do computation-wise :)

yihtserns commented 4 months ago

I was assuming it's the OP's AI that is generating that invalid JSON - so to fix the source of the problem would mean to fix their AI. 😅

cowtowncoder commented 4 months ago

Ahhhhh. Yes, that could well be.

... or the dangerous anti-pattern of "let me just do String concat, no need for fancy JSON library" in action :-D