Как лучше всего проверять входы JAX-WS?
В настоящее время я пишу новый набор веб-сервисов с использованием JAX-WS, но у меня возникают трудности с выбором наилучшего способа проверки входных данных. Я могу сделать некоторые проверки в моих классах реализации, но некоторые входные ошибки терпят неудачу. Например, символьные данные в числовом элементе приведут к нулевому целу в объекте JAXB.
Это те конструкции, с которыми я столкнулся.
-
@SchemaValidation
Я мог бы добавить эту аннотацию к классу конечных точек, и JAX-WS позаботится о проверке. Это работало локально в tomcat, но есть опасения, что он не будет работать на некоторых серверах. Моя главная проблема заключается в том, что я должен сдать контроль над тем, как ошибки выводятся в ответе.
-
Все входы как строки
Я ненавижу этот подход, но я видел другие веб-службы, где все входы определяются как строки. Это уловило бы случайные данные в числовом элементе, поскольку я мог бы проверить его, где я называю наш API, хотя вы все равно пропустите любые некорректно названные xml-элементы.
Я действительно хочу, чтобы ошибки возвращались так же, как ошибки API, а не как мыльная ошибка. Есть идеи? Я видел, как несколько сайтов говорили о перехвате запроса с помощью своего рода фильтра. Не уверен, как это будет работать с различными ответами для разных операций.
например.
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<myOperationResponse>
<return>
<success>false</success>
<errors>
<error>
<code>UNIQUECODE</code>
<message>Message text</message>
</error>
</errors>
</return>
</myOperationResponse>
</S:Body>
</S:Envelope>
Возможно, я слишком много спрашиваю, но думал, что посмотрю, пропустил ли я что-нибудь. ТИА.
Ответы
Ответ 1
Нашел эту статью, которая объясняет один из возможных способов.
http://one-size-doesnt-fit-all.blogspot.co.uk/2009/04/jax-ws-schemavalidation-custom-handler.html
Я возвращаю сообщение об ошибке синтаксического анализа в стандартную макет ответа. Мне просто нужно проверить, что он будет работать на машине для клиентов. (Некоторые говорят, что у них были проблемы с @SchemaValidation)
Ответ 2
Если вы настаиваете на контроле (что-то вроде того, что вам обычно нужно отказываться при выполнении Jax-WS...), вы можете реализовать Провайдер и валидатор, проверяющий схему XSD.
Схема XSD позаботится о проверке ввода (тип и потенциальные перечисления, сопоставление образцов и т.д.)
Чтобы реализовать javax.xml.ws.Provider
в качестве конечной точки SOAP, создайте класс, похожий на
@javax.xml.ws.ServiceMode(value = javax.xml.ws.Service.Mode.MESSAGE)
@javax.xml.ws.WebServiceProvider(
wsdlLocation = "WEB-INF/wsdl/MyService.wsdl",
targetNamespace = "urn-com-acme-webservice",
serviceName = "ProcessPurchaseOrderService",
portName = "ProcessPurchaseOrderPort"
)
public class ProcessPurchaseOrder implements Provider<SOAPMessage> {
@override
public SOAPMessage invoke(final SOAPMessage request) {
//see below
}
}
A SOAPMessage
будет передан методу invoke
, который ожидает в ответ допустимый ответ или SOAPFault, завернутый в SOAPMessage;
Чтобы снова проверить XSD, используйте javax.xml.validator
:
URL url = this.getClass().getResource(xsdSchemaLocation);
String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
SchemaFactory factory = SchemaFactory.newInstance(language);
Schema schema = factory.newSchema(url);
validator = schema.newValidator();
Извлеките SOAPBody
xml и проверьте его на Validator
с помощью метода validate()
.
Поймать исключения из проверки и создать собственную ошибку SOAP:
//Build the SOAP Fault Response
MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
SOAPMessage response = factory.createMessage();
SOAPFault fault = response.getSOAPBody().addFault();
fault.setFaultString(myCustomErrorString);
fault.addDetail().addChildElement("exception").addTextNode(myCustomErrorId);
затем верните SOAPMessage, содержащий ошибку.
(нет, мне не нравятся веб-службы SOAP)
Ответ 3
В сценарии, который вы пытаетесь достичь, не будет никакой ошибки SOAP. Логика проверки (которая будет частью кода, который обрабатывает запрос в конце концов), должна обеспечить, чтобы все сценарии проверки были обработаны.
Мы столкнулись с такими сценариями, когда третье лицо, интегрировавшее наши веб-службы, не могло многое расшифровать из-за ошибок SOAP, и мы пошли, создав ответ об ошибке так же, как и вы. Я бы предложил следующий подход.
- Напишите свою собственную логику проверки
- Создайте соответствующую структуру объекта. У вас уже есть один в формате XML. Просто нужно объективировать его.
- Вызовите эту логику проверки и передайте ей входные объекты. Логика проверки будет проверять все входы и заполнять соответствующий объект ответа (
myOperationResponse
).
- При возврате метода проверки проверьте состояние или объекты ошибки. Если есть ошибки, верните объект ответа или продолжите обработку запроса дальше, а затем верните ответ успеха.
Ответ 4
Я не уверен, что я понимаю u правильно, но maby это помогает u:
http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html