6

いくつかのかなり基本的なPOJOエンティティでJAX-RSを使用しており、いくつかの@GET注釈@POST付きメソッドが@Produceあり@Consume MediaType.APPLICATION_JSONますMediaType.APPLICATION_XML。壮観なものはありません。

私が持っている質問は、入ってくるデータをどのように検証するのが最善かということです。

XMLスキーマは生成できますが、ありません。私はこれをどういうわけかひどく魅力的に見えないものに引っ掛ける必要があるでしょう、そして私はまだ簡潔な例を見つけていません。

「BeanValidation」を使用することもできますが、これをどのように接続して呼び出すことができるかわかりません。

最後に(私は思う)、たとえばisValidForXXX()、エンティティPOJOにいくつかのメソッドを追加し、インスタンスが渡されるたびにそれらを呼び出すことができます。

誰かの推薦?

4

3 に答える 3

2

XMLスキーマがある場合は、内でJAXB検証を使用できますMessageBodyReader。具体的な例については、同様の質問に対する私の回答を参照してください。

ValidatingReader

以下は、MessageBodyReader4つのことを行うための必要最低限​​の実装です:1)Create a JAXBContext、2)のインスタンスを作成しますSchema。3)スキーマを設定しますUnmarshaller。4)をアンマーシャルしInputStreamます。

package org.example;

import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URL;

import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.*;
import javax.xml.XMLConstants;
import javax.xml.bind.*;
import javax.xml.validation.*;

@Provider
@Consumes("application/xml")
public class ValidatingReader implements MessageBodyReader<Customer> {

    @Context
    protected Providers providers;

    private Schema schema;
    private JAXBContext jaxbContext;

    public ValidatingReader() {
        try {
            JAXBContext jc = JAXBContext.newInstance(Customer.class);
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            URL schemaURL = null; // URL for your XML schema
            schema = sf.newSchema(schemaURL);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) {
        return arg0 == Customer.class;
    }

    public Customer readFrom(Class<Customer> arg0, Type arg1, Annotation[] arg2, MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
            throws IOException, WebApplicationException {
        try {
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            unmarshaller.setSchema(schema);
            return (Customer) unmarshaller.unmarshal(arg5);
        } catch(JAXBException e) {
            throw new RuntimeException(e);
        }
    }

}
于 2012-05-01T13:29:38.023 に答える
1

オリジナルのポスターと同じことを成し遂げようとしていました。避けたいという気持ちがあったので、MessageBodyReaderこのソリューションを共有したいと思いました。このソリューションでは、HttpServletRequestをパラメーターとして使用し、getInputStreamメソッドを使用してデータを直接操作します。

@POST
@Path("/myPath")
@Consumes(MediaType.APPLICATION_XML)
public Response saveCustomerInteraction(@Context HttpServletRequest httpRequest) {

    Response response = null;
    try {
        CustomerInteraction ci = this.handleCustomerInteractionRequest(httpRequest);
        if (ci!=null){
            // save your data or whatever your app does
        }
        else {
            response = Response.status(Status.BAD_REQUEST).entity("invalid XML").build();               
        }
    }
    catch(Exception e){
        log.error(e.getMessage(),e);
        response = Response.serverError().entity(e.getMessage()).build();
    }
    return response;
}

次に、このhandleCustomerInteractionRequestメソッドはサーブレットストリームを処理し、XMLを検証します。

protected CustomerInteraction handleCustomerInteractionRequest(HttpServletRequest request){

    CustomerInteraction ci = null;
    try {
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = sf.newSchema(schemaUrl);
        JAXBContext jaxbContext = JAXBContext.newInstance(CustomerInteraction.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        unmarshaller.setSchema(schema);
        ci = (CustomerInteraction) unmarshaller.unmarshal(request.getInputStream());    
    }
    catch (Exception e){
        // log error and return a null (or whatever you want to do with the error)
    }

    return ci;
} 
于 2015-02-20T23:11:16.603 に答える
0

優れた@BlaiseDoughanが示唆するようにMessageBodyReaderを使用すると、多くの柔軟性が得られます。明らかに、@ Consumers AnnotationとJAXBアノテーション付きクラスがすでにある場合は、これがどのように冗長に見えるかがわかります。

それは本当にあなたの快適さのレベル次第です。XMLスキーマを定義しなかったため、JAXBクラスを手動で作成し、検証ロジックを同じクラス(または外部のカスタムバリデーター)にコーディングするのが論理的であることに注意してください。

特に検証ルールを簡単に表現できる場合は、そのXMLスキーマを作成することを個人的に検討します。これは、プロジェクトにとって良い投資になる可能性があります。それ以降、JAXBクラスを自動的に生成し、検証を自動的に取得できるため、今後の保守性が向上するはずです。

于 2012-05-02T00:05:26.643 に答える