使用JAXB进行JAX-WS请求validation

在JAX-WS中,要validation传入的请求,其中一种方法是使用@SchemaValidation,如下面的链接所示。

JAX-WS和XSDvalidation

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

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

在Web服务中validation传入请求xml是否是一种标准做法,或者由于可能需要的性能影响,它是否被跳过?

像每个MVC系统一样,validation传入请求xml是一个好习惯。 (MVC可能不适合这里,但原则上,它只是视图是XML)。 如果不支持所提到的注释( @SchemaValidation ),那么一种方法是使用handler,它将使用JAXB Validationvalidation传入的请求。

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

我也不建议使用@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; } }