当前位置: 首页 > 面试题库 >

如何验证REST服务中的传入JSON数据?

卢涵畅
2023-03-14
问题内容

REST服务需要根据JSON模式验证所有传入的JSON数据。json模式是公共可访问的,可以通过http请求进行检索。

我正在使用jackson-framwork在Java和json之间进行编组和拆组。到目前为止,我找不到使用杰克逊根据模式验证数据的任何可能性。

我还尝试了JsonTools框架,该框架显然带有这种验证功能。但是很不幸,我无法通过验证工作。

我该如何进行验证?


问题答案:

我搜索了最佳实践,以对进入RESTful服务的传入json数据实施验证。我的建议是使用MessageBodyReaderreadFrom方法内部执行验证的。下面有一个message-
body-reader示例,为简单起见,它是非通用的。

我也对寻找用于执行json数据验证的最佳框架感兴趣。因为我使用jackson框架(版本1.8.5)在json和java之间进行编组和解编组,所以如果该框架提供json数据验证功能,那就太好了。不幸的是,我找不到与杰克逊一起做这件事的任何可能性。最后,我将它与https://github.com上的 json-schema-validator一起
使用。我使用的版本是2.1.7

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;

import org.codehaus.jackson.map.ObjectMapper;

import at.fhj.ase.dao.data.Address;
import at.fhj.ase.xmlvalidation.msbreader.MessageBodyReaderValidationException;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
import com.github.fge.jsonschema.exceptions.ProcessingException;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import com.github.fge.jsonschema.main.JsonValidator;
import com.github.fge.jsonschema.report.ProcessingReport;

@Provider
@Consumes(MediaType.APPLICATION_JSON)
public class AddressJsonValidationReader implements MessageBodyReader<Address> {

    private final String jsonSchemaFileAsString;

    public AddressJsonValidationReader(@Context ServletContext servletContext) {
        this.jsonSchemaFileAsString = servletContext
                .getRealPath("/json/Address.json");
    }

    @Override
    public boolean isReadable(Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {
        if (type == Address.class) {
            return true;
        }
        return false;
    }

    @Override
    public Address readFrom(Class<Address> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
            throws IOException, WebApplicationException {

        final String jsonData = getStringFromInputStream(entityStream);
        System.out.println(jsonData);

        InputStream isSchema = new FileInputStream(jsonSchemaFileAsString);
        String jsonSchema = getStringFromInputStream(isSchema);

        /*
         * Perform JSON data validation against schema
         */
        validateJsonData(jsonSchema, jsonData);

        /*
         * Convert stream to data entity
         */
        ObjectMapper m = new ObjectMapper();
        Address addr = m.readValue(stringToStream(jsonData), Address.class);

        return addr;
    }

    /**
     * Validate the given JSON data against the given JSON schema
     * 
     * @param jsonSchema
     *            as String
     * @param jsonData
     *            as String
     * @throws MessageBodyReaderValidationException
     *             in case of an error during validation process
     */
    private void validateJsonData(final String jsonSchema, final String jsonData)
            throws MessageBodyReaderValidationException {
        try {
            final JsonNode d = JsonLoader.fromString(jsonData);
            final JsonNode s = JsonLoader.fromString(jsonSchema);

            final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
            JsonValidator v = factory.getValidator();

            ProcessingReport report = v.validate(s, d);
            System.out.println(report);
            if (!report.toString().contains("success")) {
                throw new MessageBodyReaderValidationException(
                        report.toString());
            }

        } catch (IOException e) {
            throw new MessageBodyReaderValidationException(
                    "Failed to validate json data", e);
        } catch (ProcessingException e) {
            throw new MessageBodyReaderValidationException(
                    "Failed to validate json data", e);
        }
    }

    /**
     * Taken from <a href=
     * "http://www.mkyong.com/java/how-to-convert-inputstream-to-string-in-java/"
     * >www.mkyong.com</a>
     * 
     * @param is
     *            {@link InputStream}
     * @return Stream content as String
     */
    private String getStringFromInputStream(InputStream is) {
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();
    }

    private InputStream stringToStream(final String str) throws UnsupportedEncodingException {
        return new ByteArrayInputStream(str.getBytes("UTF-8"));
    }

}


 类似资料:
  • 环境:Java,泽西,jackson,汤卡特。 我有一个rest服务从客户端获取JSON输入。我想验证输入,如果它是JSON,然后它是JSON,然后JSON输入中的键是预期的或不是。如果是,那么它将产生HTTP400-bad请求。 比如-- 例如-非json输入如 null 我的代码适用于前面提到的情况2,但我希望它也适用于情况1。当非JSON输入存在时,我希望它将凭据对象设置为null,然后我可

  • 我正在使用Spring、Jersey和Hibernate(JPA)在Java中构建REST Web服务。 现在我试图在我的资源中添加对验证的支持。JSR-303(Bean验证)自然是一个合适的选择(我使用的是JSR-303的参考实现Hibernate验证器)。然而,我试图首先巩固一些概念。 在我看来,至少有两种可能的验证: 定期验证字段,例如检查属性是否为空,检查属性是否是有效的电子邮件,检查属性

  • 问题内容: 我正在使用Spring,Jersey和Hibernate(JPA)在Java中构建REST Web服务。 现在,我正在尝试在资源中添加对验证的支持。JSR-303(Bean验证)自然是一个合适的选择(我使用的是Hibernate Validator,它是JSR-303的参考实现)。但是,我尝试首先合并一些概念。 在我看来,至少有两种可能的验证: 定期验证字段 ,例如,检查属性是否为nu

  • 我有一个简单的springboot应用程序和一个Rest api。我想验证请求参数不为null/空。我将json转换成一个java对象,并从这里开始验证它们是否包含所有必需的字段,并且不为null或不为空。(对象没有保存到db)我目前正在使用javax验证方法,但是没有成功。 我还有一个包含的要素类,我需要验证(所有字段均为必填字段,而不是空或空)

  • 假设有两个微服务:订单和库存。order service中有一个API,它接受< code>ProductId 、< code>Qty等并下订单。 理想情况下,只有在库存服务中存在库存时才允许下订单。人们建议使用Saga模式或任何其他分布式事务。这很好,最终将利用一致性。 但是如果有人想滥用这个系统。他可以使用无效或缺货的产品(< code>ProductId)推送订单。系统将接受所有这些订单,并

  • 问题内容: 有谁知道如何在RESTful Web服务中编写POST方法以使用Java上传数据?我发现smartupload和commons.upload仅用于网页。 问题答案: 您可以使用一些JAX-RS库,例如Apache Wink,因此可以编写如下代码: 这样您将收到文件是。您还可以作为InputStream接收: