JAX-WS请求验证使用JAXB

6
在JAX-WS中,验证传入的请求的一种方式是使用@SchemaValidation,如下链接所示。 JAX-WS and XSD Validation 然而,我正在使用的应用服务器(WAS 7)尚不支持@SchemaValidation。(如果WAS 7支持此注释,请纠正我。)
因此,我正在寻找其他选项,例如实现处理程序来验证传入的请求。无论是在处理程序还是端点类本身中,我都可以创建JAXBContext并使用JAXB验证器。我需要显式创建JAXBContext还是它可用作资源/注释,因为JAX-WS内部使用JAXB?
这是在JAX-WS中实现验证的好方法吗?(在缺少@SchemaValidation验证的情况下)
在Web服务中验证传入的请求XML是标准做法还是因可能带来的性能损失而跳过?
2个回答

2

在每个MVC系统中,验证传入的请求XML是一个好习惯(虽然MVC可能不适用于这里,但原则上是一样的,只是视图是XML)。如果不支持上述注释(@SchemaValidation),那么一种解决方法是使用处理程序,使用JAXB验证来验证传入的请求。


2
谢谢Santosh。我已经实现了处理程序来验证传入的请求。以下链接非常有帮助link - PrasadB
确实是个不错的链接。谢谢分享。 - Santosh
链接现在已经失效 =( - secario
PrasadB发布的链接现在是https://dzone.com/articles/jax-ws-payload-validation-and。 - Pino

0

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

另外,我不建议使用 @SchemaValidation,因为它是供应商特定的而不是标准的。

话虽如此,当我在玩弄我的 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;
    }

}

谢谢,Archimedis。我会检查 DataPower 是否是我们组织的选择。另外,我认为 @SchemaValidation 是 JAX-WS 标准的一部分,而不是供应商特定的。我使用了一个 JAX-WS 处理程序来验证,因为我需要在将传入的 XML 解组成 Java 对象之前验证它。 - PrasadB
我有一个旧的实现,它使用JAX-WS处理程序,但我发现它是特定于SOAP的,所以我决定尝试使用拦截器,因为它不需要特定于SOAP。 - Archimedes Trajano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接