[英]JAX-WS request validation using JAXB
在JAX-WS中,要驗證傳入請求,其中一種方法是使用@SchemaValidation,如下面的鏈接所示。
但是,我使用的應用程序服務器(WAS 7)尚不支持@SchemaValidation。 (如果WAS 7確實支持此注釋,請更正我)
所以我正在尋找其他選項,比如實現一個處理程序來驗證傳入的請求。 無論是在處理程序還是端點類本身,我都可以創建JAXBContext並使用JAXB驗證器。 我是否需要顯式創建JAXBContext,或者它是否可用作資源/注釋,因為JAX-WS內部使用JAXB? 這是在JAX-WS中實現驗證的好方法嗎? (在沒有@SchemaValidation驗證的情況下)
在Web服務中驗證傳入的請求xml是否是一種標准做法,或者由於可能需要的性能影響,它是否被跳過?
像每個MVC系統一樣,驗證傳入請求xml是一個好習慣。 (MVC可能不適合這里,但原則上,它只是視圖是XML)。 如果不支持提到的注釋( @SchemaValidation
),那么一個出路就是使用handler,它將使用JAXB Validation驗證傳入的請求。
如果您是一個大型組織,更好的做法是使用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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.