【问题标题】:JAX-WS request validation using JAXB使用 JAXB 的 JAX-WS 请求验证
【发布时间】:2012-01-05 14:12:21
【问题描述】:

在 JAX-WS 中,要验证传入的请求,其中一种方法是使用下面链接中建议的 @SchemaValidation。

JAX-WS and XSD Validation

但是,我正在使用的应用程序服务器 (WAS 7) 尚不支持 @SchemaValidation。 (如果 WAS 7 确实支持这个注释,请纠正我)

所以我正在寻找其他选项,例如实现处理程序来验证传入请求。在处理程序或端点类本身中,我可以创建 JAXBContext 并使用 JAXB 验证器。我需要显式地创建 JAXBContext 还是因为 JAX-WS 在内部使用 JAXB,所以它可以作为资源/注释使用? 这是在 JAX-WS 中实现验证的好方法吗? (在没有@SchemaValidation 验证的情况下)

在 Web 服务中验证传入的请求 xml 是一种标准做法,还是由于可能需要的性能损失而被跳过?

【问题讨论】:

    标签: java web-services validation jaxb jax-ws


    【解决方案1】:

    像每个 MVC 系统一样验证传入请求 xml 是一种很好的做法。 (MVC 可能不适合这里,但原则上,它与视图是 XML 相同)。如果不支持提到的注释(@SchemaValidation),那么一种方法是使用处理程序,它将使用JAXB Validation 验证传入请求。

    【讨论】:

    【解决方案2】:

    如果您是大型组织,更好的做法是使用 DataPower。它将为您进行验证以及各种功能。就最佳实践而言,我建议使用 DataPower,因为它就是为此而设计的,但是您需要确保开发的代码也可以验证,否则您会在运行时遇到验证问题。

    我也不建议使用 @SchemaValidation,因为这是特定于供应商的,而不是标准的。

    话虽如此,当我为不使用任何供应商特定 API 的参考 Java EE 应用程序使用拦截器时,我编写了以下内容。

    /**
     * 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;
        }
    
    }
    

    【讨论】:

    • 感谢阿基米迪斯。我将检查 DataPower 是否是我们组织中的一个选项。另外,我认为@SchemaValidation 是 JAX-WS 标准的一部分,而不是特定于供应商的。我使用 JAX-WS 处理程序进行验证,因为我需要在解组到 Java 对象之前验证传入的 xml
    • 我有一个使用 JAX-WS 处理程序的旧实现,但我发现它是特定于 SOAP 的,所以我决定尝试使用拦截器,因为它不需要特定于 SOAP。
    猜你喜欢
    • 2019-05-09
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    相关资源
    最近更新 更多