Проверка запроса JAX-WS с использованием JAXB - PullRequest
6 голосов
/ 24 ноября 2011

В JAX-WS для проверки входящего запроса одним из способов является использование @SchemaValidation, как предлагается в приведенной ниже ссылке.

Проверка JAX-WS и XSD

Однако сервер приложений (WAS 7), который я использую, еще не поддерживает @SchemaValidation. (Пожалуйста, исправьте меня, если WAS 7 поддерживает эту аннотацию)

Так что я смотрю на другие варианты, такие как реализация обработчика для проверки входящего запроса. Либо в обработчике, либо в самом классе конечных точек я могу создать JAXBContext и использовать валидатор JAXB. Нужно ли создавать JAXBContext явно или он доступен в виде ресурса / аннотации, поскольку JAX-WS внутренне использует JAXB? Это хороший способ реализовать валидацию в JAX-WS? (При отсутствии проверки @SchemaValidation)

Это стандартная практика для проверки входящего XML-запроса в веб-службах или он пропущен из-за снижения производительности, которое может потребоваться?

Ответы [ 2 ]

2 голосов
/ 24 ноября 2011

Хорошей практикой является проверка xml входящего запроса, как в случае с каждой системой MVC. (MVC здесь может не подходить, но в принципе это то же самое, что представление является XML). Если упомянутая аннотация (@SchemaValidation) не поддерживается, то одним из выходов является использование обработчика, который будет проверять входящий запрос, используя JAXB Validation .

0 голосов
/ 27 ноября 2011

Лучше практиковаться, если вы БОЛЬШАЯ организация - использовать 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;
    }

}
...