java - 尝试通过 Spring Boot Rest 使用 Jackson 验证 JSON

标签 java json spring-mvc jackson spring-boot

我正在尝试使用 Spring Boot 创建一个 RESTful Web 服务,它将接收 JSON 并使用 Jackson 对其进行验证。

这是 RESTful Web 服务:

import java.util.Map;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.google.gson.Gson;

@RestController
@RequestMapping("/myservice")
public class ValidationService {    

    @RequestMapping(value="/validate", method = RequestMethod.POST)
    public void validate(@RequestBody Map<String, Object> payload) throws Exception {
        Gson gson = new Gson();
        String json = gson.toJson(payload); 
        System.out.println(json);
        boolean retValue = false;

        try {
            retValue = Validator.isValid(json);
        } 
        catch(Throwable t) {
            t.printStackTrace();
        }
        System.out.println(retValue);

    }
}

这是 validator 的代码:

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Validator {

    public static boolean isValid(String json) {
        boolean retValue = false;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
            JsonParser parser = objectMapper.getFactory().createParser(json);
            while (parser.nextToken() != null) {}
            retValue = true;
            objectMapper.readTree(json);
        }catch(JsonParseException jpe) {
            jpe.printStackTrace();
        }
        catch(IOException ioe) {

        }
        return retValue;
    }
}

所以,当我使用curl发送有效的JSON时:

curl -H "Accept: application/json" -H "Content-type: application/json" \ 
-X POST -d '{"name":"value"}' http://localhost:8080/myservice/validate

我收到以下信息到标准输出:

{"name":"value"}
true

但是当使用以下curl命令来处理无效的JSON时(故意删除右大括号):

curl -H "Accept: application/json" -H "Content-type: application/json" \
 -X POST -d '{"name":"value"' http://localhost:8080/myservice/validate

我在标准输出中收到以下内容:

{"timestamp":1427698779063,
 "status":400,"error":
 "Bad Request",
 "exception":"org.springframework.http.converter.HttpMessageNotReadableException",
 "message":"Could not read JSON: 
 Unexpected end-of-input: expected close marker for OBJECT 
 (from [Source: java.io.PushbackInputStream@1edeb3e; line: 1, column: 0])\n
 at [Source: java.io.PushbackInputStream@1edeb3e; line: 1, column: 31]; 
 nested exception is
 com.fasterxml.jackson.core.JsonParseException: 
 Unexpected end-of-input: expected close marker for OBJECT 
 (from [Source: java.io.PushbackInputStream@1edeb3e; line: 1, column: 0])\n 
 at [Source: java.io.PushbackInputStream@1edeb3e; line: 1, column: 31]",
 "path":"/myservice/validate"

有没有办法确保异常在服务器端处理,但不会抛出到标准输出中,然后让我的代码响应:

false

感谢您花时间阅读本文...

最佳答案

明白了!

添加了以下更改:

@RequestMapping 代码部分内:

consumes = "text/plain",
produces = "application/json"

将 @RequestBody 从 Map 更改为 String 有效负载。

ValidationService类:

@RequestMapping(value="/validate", 
                method = RequestMethod.POST, 
                consumes="text/plain", 
                produces="application/json")
public ValidationResponse process(@RequestBody String payload) throws JsonParseException,
                                                                      IOException {
    ValidationResponse response = new ValidationResponse();
    boolean retValue = false;
    retValue = Validator.isValid(payload);
    System.out.println(retValue);
    if (retValue == false) {
        response.setMessage("Invalid JSON");
    }
    else {
        response.setMessage("Valid JSON");
    }
    return response;
}

validator 类:

import java.io.IOException;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Validator {

    public static boolean isValid(String json) {
        boolean retValue = true;
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
            JsonFactory factory = mapper.getFactory();
            JsonParser parser = factory.createParser(json);
            JsonNode jsonObj = mapper.readTree(parser);
            System.out.println(jsonObj.toString());
        }
        catch(JsonParseException jpe) {
            retValue = false;   
        }
        catch(IOException ioe) {
            retValue = false;
        }
        return retValue;
    }
}

验证响应:

public class ValidationResponse {

    public String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

使用“text/plain”作为内容类型:

curl -H "Accept: application/json" -H "Content-type: text/plain" -X POST -d \ 
 '{"name":"value"}' http://localhost:8080/myservice/validate

现在,一切正常!这太棒了!

关于java - 尝试通过 Spring Boot Rest 使用 Jackson 验证 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29340290/

相关文章:

java - 将对象添加到 ArrayList - 获得 n 次最后找到的对象

json - GraphQL/React 抛出网络错误 JSON.parse : unexpected character at line 1 column 1 of the JSON data

ios - URLSession 从 HTTP GET 请求返回空数组

java - Spring中无法导入 `configureRepositoryRestConfiguration`

java - HTTP 状态 500 - 实例化 servlet 类 org.springframework.web.servlet.DispatcherServlet 时出错

java - MySql 出现 JAVA 错误。上一个成功发送到服务器的数据包是 0 毫秒前

java - MQ 客户端应用程序连接到客户端

java - netbeans 保存附加源的位置(JavaDoc、源)

c# - serializer.Deserialize<T>() 上的字符串实习生

spring-mvc - Mockito 验证 post 对象具有相同的值而不是相同的对象引用