简体   繁体   English

使用JAXB进行JAX-WS请求验证

[英]JAX-WS request validation using JAXB

In JAX-WS, to validate the incoming request, one of the ways is to use @SchemaValidation as suggested in below link. 在JAX-WS中,要验证传入请求,其中一种方法是使用@SchemaValidation,如下面的链接所示。

JAX-WS and XSD Validation JAX-WS和XSD验证

However the application server (WAS 7) I am using does not yet support @SchemaValidation. 但是,我使用的应用程序服务器(WAS 7)尚不支持@SchemaValidation。 (Please correct me if WAS 7 does support this annotation) (如果WAS 7确实支持此注释,请更正我)

So I am looking at other options like implementing a handler to validate the incoming request. 所以我正在寻找其他选项,比如实现一个处理程序来验证传入的请求。 Either in the handler or the endpoint class itself, I can create the JAXBContext and use the JAXB validator. 无论是在处理程序还是端点类本身,我都可以创建JAXBContext并使用JAXB验证器。 Do I need to create the JAXBContext explicitly or is it available as a resource / annotation since JAX-WS internally uses JAXB? 我是否需要显式创建JAXBContext,或者它是否可用作资源/注释,因为JAX-WS内部使用JAXB? Is this a good way to implement validation in JAX-WS? 这是在JAX-WS中实现验证的好方法吗? (In the absence of @SchemaValidation validation) (在没有@SchemaValidation验证的情况下)

Is it a standard practice to validate the incoming request xml in web services or is it given a skip due to performance hit it might take? 在Web服务中验证传入的请求xml是否是一种标准做法,或者由于可能需要的性能影响,它是否被跳过?

It is a good practice to validate the incoming request xml as is the case with every MVC system. 像每个MVC系统一样,验证传入请求xml是一个好习惯。 (MVC might not fit here but in principle, its same just that the view is XML). (MVC可能不适合这里,但原则上,它只是视图是XML)。 If the mentioned annotation ( @SchemaValidation ) is not supported, then one way out is is use handler which will validate the incoming request using JAXB Validation . 如果不支持提到的注释( @SchemaValidation ),那么一个出路就是使用handler,它将使用JAXB Validation验证传入的请求。

Better practice if you are a LARGE organization is to use DataPower. 如果您是一个大型组织,更好的做法是使用DataPower。 It will do the validations for you along with a variety of features. 它将为您进行验证以及各种功能。 As far as best practice goes, I would suggest DataPower just because it was designed for that, but you need to make sure you develop code that can validate as well otherwise you'd hit the validation issues on runtime. 就最佳实践而言,我建议DataPower只是因为它是为此设计的,但您需要确保开发可以验证的代码,否则您会在运行时遇到验证问题。

I also do NOT recommend using @SchemaValidation since that is vendor specific rather than standard. 我也不建议使用@SchemaValidation,因为这是特定于供应商而非标准。

That being said, I wrote the following when I was playing around interceptors for my reference Java EE application which does not use any vendor specific APIs. 话虽这么说,当我在我的参考Java EE应用程序中使用拦截器时,我写了以下内容,该应用程序不使用任何特定于供应商的API。

/**
 * Validates the XML streams going in the request and response if the log level
 * is {@link Level#FINER} or below against {@value #LOGGER_NAME}. If
 * {@link Level#FINEST} is used it will also dump the XML that were sent.
 * 
 * @author Archimedes Trajano
 * 
 */
public class XmlValidationInterceptor {
    /**
     * Logger.
     */
    private static final Logger LOG;

    /**
     * Name of the logger.
     */
    public static final String LOGGER_NAME = "xml.validation"; //$NON-NLS-1$

    static {
        LOG = Logger.getLogger(LOGGER_NAME, "Messages"); //$NON-NLS-1$
    }

    /**
     * Contains a composite of multiple schema files into one schema that used
     * on all message validations.
     */
    private final Schema schema;

    /**
     * Loads up the schema into memory. This uses the default
     * 
     * @throws SAXException
     *             problem parsing the schema files.
     */
    public XmlValidationInterceptor() throws SAXException {
        final SchemaFactory sf = SchemaFactory
                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        schema = sf.newSchema();
    }

    /**
     * Loads up the schema from the specified array of {@link Source} into
     * memory.
     * 
     * @param schemaSources
     *            schema sources.
     * @throws SAXException
     *             problem parsing the schema files.
     */
    public XmlValidationInterceptor(final Source... schemaSources)
            throws SAXException {
        final SchemaFactory sf = SchemaFactory
                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        schema = sf.newSchema(schemaSources);
    }

    /**
     * Writes the object as XML to the logger.
     * 
     * @param param
     *            object to marshal
     * @param context
     *            invocation context used for logging.
     * @throws JAXBException
     *             problem with the Java binding except schema issues because
     *             schema validation errors are caught and processed
     *             differently.
     */
    private void marshalObject(final Object param,
            final InvocationContext context) throws JAXBException {
        if (!param.getClass().isAnnotationPresent(XmlRootElement.class)) {
            return;
        }

        // validate against known schemas
        final JAXBContext jaxbContext = JAXBContext.newInstance(param
                .getClass());
        final Marshaller m = jaxbContext.createMarshaller();
        m.setSchema(schema);
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        try {
            final StringWriter w = new StringWriter();
            m.marshal(param, w);
            LOG.finest(w.toString());
        } catch (final MarshalException e) {
            if (!(e.getLinkedException() instanceof SAXParseException)) {
                throw e;
            }
            final SAXParseException parseException = (SAXParseException) e
                    .getLinkedException();
            LOG.log(Level.SEVERE,
                    "XmlValidationInterceptor.parseException", // $NON-NLS-1$
                    new Object[] { context.getMethod(), param,
                            parseException.getMessage() });
            m.setSchema(null);
            final StringWriter w = new StringWriter();
            m.marshal(param, w);
            LOG.finest(w.toString());
        }
    }

    /**
     * Validates the data in the parameters and return values.
     * 
     * @param context
     *            invocation context
     * @return invocation return value
     * @throws Exception
     *             invocation exception
     */
    @AroundInvoke
    public Object validate(final InvocationContext context) throws Exception {
        if (!LOG.isLoggable(Level.FINER)) {
            return context.proceed();
        }

        final Object[] params = context.getParameters();
        for (final Object param : params) {
            marshalObject(param, context);
        }

        final Object ret = context.proceed();
        if (ret != null) {
            marshalObject(ret, context);
        }
        return ret;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM