24

残りのサービスは、json スキーマに対してすべての着信 json データを検証する必要があります。json スキーマは公開されており、http 要求を介して取得できます。

javaとjsonの間のマーシャリングとアンマーシャリングにjackson-framworkを使用しています。これまでのところ、jackson を使用してスキーマに対してデータを検証する可能性を見つけることができませんでした。

また、このような検証機能を明らかに提供するJsonToolsフレームワークも試しました。残念ながら、検証を機能させることはできませんでした。JsonTool スキーマ検証が機能しないのはなぜですか?

どうすればそのような検証を行うことができますか?

4

3 に答える 3

17

着信 json データの検証を RESTful サービスに適用するためのベスト プラクティスを探しました。私の提案は、メソッドMessageBodyReader内で検証を実行する a を使用することです。readFrom以下に、単純化のために一般的ではないメッセージ本文リーダーの例を示します。

また、json データの検証を行うための最適なフレームワークを見つけることにも興味がありました。json と java 間のマーシャリングとアンマーシャリングに jackson フレームワーク (バージョン 1.8.5) を使用しているため、このフレームワークが 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"));
    }

}
于 2013-08-12T17:46:01.563 に答える
8
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import com.github.fge.jackson.JsonLoader;
import com.fasterxml.jackson.databind.JsonNode;

public class ValidationJSON {
    public static void main(String[] arr){
       String jsonData = "{\"name\": \"prem\"}";
       String jsonSchema = ""; //Schema we can generate online using http://jsonschema.net/
       final JsonNode data = JsonLoader.fromString(jsonData);
       final JsonNode schema = JsonLoader.fromString(jsonSchema);

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

       ProcessingReport report = validator.validate(schema, data);
       System.out.println(report.isSuccess());
    }

}
于 2016-06-03T01:52:14.870 に答える