如何从 Java 中的 JSON 对象中删除所有 JSON 格式(不仅仅是空格)?

How to remove all JSON formatting (not just whitespace) from a JSON object in Java?

我有一个这样的 JSON 对象:

{
    "shippingLines": [{
        "carrier": "NZ Post",
        "price": {
            "amount": 5.50,
            "currency": "NZD"
        }
    }],
    "taxAmount": {
        "amount": 5.325,
        "currency": "NZD"
    },
    "reference": "INV000045",
    "totalAmount": {
        "amount": 35.5,
        "currency": "NZD"
    },
    "returnUrls": {
        "successUrl": "http://yourserver/success",
        "failUrl": "http://yourserver/fail",
        "callbackUrl": "http://yourserver/fail-safe-callback"
    }
}

我想从中删除所有 JSON 格式(空格、逗号、括号、方括号、引号、冒号)并生成如下输出:

shippingLinescarrierNZPostpriceamount5.50currencyNZDtaxAmountamount5.325currencyNZDreferenceINV000045totalAmountamount35.5currencyNZDreturnUrlssuccessUrlhttp://yourserver.com/successfailUrlhttp://.yourserver.com/failcallbackUrlhttp://yourserver.com/fail-safe-callback

所以我尝试了一堆 replaceAll() 如下所示:

String json = objectMapper.writeValueAsString(<Json Class here>); // using Jackson
json.replaceAll("\"", "")
    .replaceAll("\{","")
    .replaceAll("\}","")
    .replaceAll("\[","")
    .replaceAll("\]","")
    .replaceAll(":","")
    .replaceAll(",","")
    .replaceAll(" ","");

但这也替换了 URL 中的 "colon" (http://...) 在 returnUrls 对象中。 有没有更好的方法来实现这一目标?

注意:我在Java 7.

要删除键后的冒号首先只删除

":

完成后得到新字符串。现在删除

"

分三步就可以了,不知道你有没有其他情况。

第 1 步:将所有 http:// 替换为某物。例如,http:__

第 2 步:您当前的。

第 3 步:与第 1 步相反。

如果问题完全是 http://,那么您可以将 http// 替换为原来的 http://

   String output1=    json.replaceAll("\"", "")
                    .replaceAll("\{","")
                    .replaceAll("\}","")
                    .replaceAll("\[","")
                    .replaceAll("\]","")
                    .replaceAll(":","")
                    .replaceAll(",","")
                    .replaceAll(" ","")
                    .replaceAll("\\","")
                    .replaceAll("http//", "http://");

不过要小心,因为如果您的 json 曾经包含您不想替换的 http//,这将导致不需要的替换。

一个字符一个字符地查找。按原样复制引号之间的内容

String json = objectMapper.writeValueAsString(<Json Class here>); // using Jackson
String output = "";
int len = json.length();
boolean inQuotes = false;
for (int i = 0; i < len; i++)
{
    char c = json.charAt(i);
    if (c == '\"')
    {
        inQuotes = !inQuotes;
        continue;
    }
    if (inQuotes)
    {
        output = output + c;
    }
}

在附加到字符串、StringBuilder 等方面进行了优化...但以上是它的基本要点。

正如其他人所指出的,这不处理字符串中转义序列的情况:

"A string with an \"escaped\" quote include \u1234 and \b or \t"

我将把它留给你作为练习。

您可以使用正则表达式。这对你有帮助。

正则表达式 [^a-zA-Z0-9-./]

public class Test {

    public static void main(String[] args) {
        String jsonString = "{\n" +
                "    \"shippingLines\": [{\n" +
                "        \"carrier\": \"NZ Post\",\n" +
                "        \"price\": {\n" +
                "            \"amount\": 5.50,\n" +
                "            \"currency\": \"NZD\"\n" +
                "        }\n" +
                "    }],\n" +
                "    \"taxAmount\": {\n" +
                "        \"amount\": 5.325,\n" +
                "        \"currency\": \"NZD\"\n" +
                "    },\n" +
                "    \"reference\": \"INV000045\",\n" +
                "    \"totalAmount\": {\n" +
                "        \"amount\": 35.5,\n" +
                "        \"currency\": \"NZD\"\n" +
                "    },\n" +
                "    \"returnUrls\": {\n" +
                "        \"successUrl\": \"http://yourserver/success\",\n" +
                "        \"failUrl\": \"http://yourserver/fail\",\n" +
                "        \"callbackUrl\": \"http://yourserver/fail-safe-callback\"\n" +
                "    }\n" +
                "}";
        String format = jsonString.replaceAll("[^a-zA-Z0-9-./]", "");
    }
}

我们可以先转成yaml,这样替换起来会更简单更通用。 Like here

import java.io.IOException;

import org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;

public class Library {

    public static String asYaml(String jsonString) throws JsonProcessingException, IOException {
        // parse JSON
        JsonNode jsonNodeTree = new ObjectMapper().readTree(jsonString);
        // save it as YAML
        String jsonAsYaml = new YAMLMapper().writeValueAsString(jsonNodeTree);
        return jsonAsYaml;
    }
    public static void main(String[] args) {
        String jsonStr = "{\r\n" + 
                "    \"shippingLines\": [{\r\n" + 
                "        \"carrier\": \"NZ Post\",\r\n" + 
                "        \"price\": {\r\n" + 
                "            \"amount\": 5.50,\r\n" + 
                "            \"currency\": \"NZD\"\r\n" + 
                "        }\r\n" + 
                "    }],\r\n" + 
                "    \"taxAmount\": {\r\n" + 
                "        \"amount\": 5.325,\r\n" + 
                "        \"currency\": \"NZD\"\r\n" + 
                "    },\r\n" + 
                "    \"reference\": \"INV000045\",\r\n" + 
                "    \"totalAmount\": {\r\n" + 
                "        \"amount\": 35.5,\r\n" + 
                "        \"currency\": \"NZD\"\r\n" + 
                "    },\r\n" + 
                "    \"returnUrls\": {\r\n" + 
                "        \"successUrl\": \"http://yourserver/success\",\r\n" + 
                "        \"failUrl\": \"http://yourserver/fail\",\r\n" + 
                "        \"callbackUrl\": \"http://yourserver/fail-safe-callback\"\r\n" + 
                "    }\r\n" + 
                "}";
        try {
            String ymlstr = asYaml(jsonStr);
            System.out.println(ymlstr);
            ymlstr=StringUtils.replace(ymlstr, ":", "");
            ymlstr=StringUtils.replace(ymlstr, "-", "");
            ymlstr=StringUtils.replace(ymlstr, "\n", "");
            ymlstr=StringUtils.replace(ymlstr, " ", "");
            ymlstr=StringUtils.replace(ymlstr, "\"", "");
            System.out.println(ymlstr);
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
} 

Maven 依赖项:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.8.6</version>
</dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.6</version>
</dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml -->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-yaml</artifactId>
    <version>2.8.6</version>
</dependency>

输出:

shippingLinescarrierNZPostpriceamount5.5currencyNZDtaxAmountamount5.325currencyNZDreferenceINV000045totalAmountamount35.5currencyNZDreturnUrlssuccessUrlhttp//yourserver/successfailUrlhttp//yourserver/failcallbackUrlhttp//yourserver/failsafecallback

这是另一种方法。这个想法是遍历所有元素,return它们的字符串表示,删除空格。

// Takes input and returns a string with all elements concatenated.
// withExactBigDecimals(true) makes sure trailing zeros (e.g. 5.50) will be
// preserved
static String toRawConcat(String input) throws IOException {
    ObjectMapper mapper = new ObjectMapper()
        .configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
        .configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true)
        .setNodeFactory(JsonNodeFactory.withExactBigDecimals(true));
    JsonNode node = mapper.readTree(input);
    return nodeToString(node);
}

// Removes whitespaces from a string
static String removeWs(String input) {
    return input.replaceAll("\s+", "");
}

// Inspects the node type and returns the node contents as a string
private static String nodeToString(JsonNode node) {
    switch (node.getNodeType()) {
        case NULL:
        case BOOLEAN:
        case STRING:
            return removeWs(node.asText());
        case NUMBER:
            return node.decimalValue().toString();
        case ARRAY:
            {
                String s = "";
                Iterator<JsonNode> it = node.elements();
                while (it.hasNext()) {
                    s += nodeToString(it.next());
                }
                return s;
            }
        case OBJECT:
            {
                String s = "";
                Iterator<Entry<String, JsonNode>> it = node.fields();
                while (it.hasNext()) {
                    Entry<String, JsonNode> sub = it.next();
                    s += removeWs(sub.getKey()) + nodeToString(sub.getValue());
                }
                return s;
            }
        default:
            throw new UnsupportedOperationException("Node type " + node.getNodeType() + " not supported");
    }

顺便说一句,如果你想去掉所有看起来不像节点值的东西(例如,你希望 "NZ Post" 变成 "NZPost"),你为什么首先将它解析为 JSON?