Web Services 如何自定义JAX-WS RuntimeException响应?

e5njpo68  于 2023-11-22  发布在  其他
关注(0)|答案(2)|浏览(240)

我试图自定义在到达WebMethod之前抛出的RuntimeException的错误响应,例如无效的xml主体或JAX-WS服务的错误方法名称。我试图使用@HandlerChain的处理程序,但响应在处理程序处理之前发送。
这里有一个例子。假设我在我的ws中有一个copyTool方法,但客户端发送了下面的请求。我希望能够自定义响应,以便我可以更改faultString或返回一些自定义faultCode。

输入

  1. <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  2. xmlns:cor="http://acme.com/">
  3. <soapenv:Header/>
  4. <soapenv:Body>
  5. <cor:copyTool>
  6. <toolNumber>some Text instead of Integer</toolNumber>
  7. </cor:copyTool>
  8. </soapenv:Body>
  9. </soapenv:Envelope>

字符串

输出

  1. <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  2. <S:Body>
  3. <ns0:Fault xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.w3.org/2003/05/soap-envelope">
  4. <faultcode>ns0:Server</faultcode>
  5. <faultstring>Exception Description: The object [some Text instead of Integer], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[toolNumber-->toolNumber/text()]] with descriptor [XMLDescriptor(com.acme --> [DatabaseTable(ns0:copyTool)])], could not be converted to [class java.lang.Integer].
  6. Internal Exception: java.lang.NumberFormatException: For input string: "some Text instead of Integer"</faultstring>
  7. </ns0:Fault>
  8. </S:Body>
  9. </S:Envelope>

kg7wmglp

kg7wmglp1#

我认为你可以尝试使用ExceptionMapper,如下所示:

  1. @Provider
  2. public class WebApplicationExceptionMapper implements ExceptionMapper<Exception>{
  3. @Override
  4. public Response toResponse(Exception exception) {
  5. Response.Status responseStatus = THE_STATUS_YOU_WANT_BASED_ON_THE_EXCEPTION;
  6. return Response.status(responseStatus).entity(THE_ERROR_ENTITY_YOU_WANT_BASED_ON_THE_EXCEPTION).build();
  7. }
  8. }

字符串

hmae6n7t

hmae6n7t2#

我可以通过@HandlerChainRuntimeException自定义故障消息。我猜你做错了什么。

一步一步的过程中,我做了什么,使它的工作:

我创建了一个示例项目来演示。

项目结构(Maven项目):

x1c 0d1x的数据

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>org.example</groupId>
  7. <artifactId>customize-fault-jaxws</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <properties>
  10. <maven.compiler.source>17</maven.compiler.source>
  11. <maven.compiler.target>17</maven.compiler.target>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. </properties>
  14. <dependencies>
  15. <dependency>
  16. <groupId>javax.xml.ws</groupId>
  17. <artifactId>jaxws-api</artifactId>
  18. <version>2.3.1</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>com.sun.xml.ws</groupId>
  22. <artifactId>jaxws-rt</artifactId>
  23. <version>2.3.7</version>
  24. </dependency>
  25. </dependencies>
  26. </project>

字符串

PublishLotteryService:

  1. package org.example.endpoint;
  2. import org.example.webservice.LotteryServiceImpl;
  3. import javax.xml.ws.Endpoint;
  4. public class PublishLotteryService {
  5. public static void main(String[] args) {
  6. Endpoint.publish("http://localhost:8080/webservice/lottery", new LotteryServiceImpl());
  7. }
  8. }

LotteryService(一种WebService接口):

  1. package org.example.webservice;
  2. import javax.jws.WebMethod;
  3. import javax.jws.WebService;
  4. import javax.jws.soap.SOAPBinding;
  5. import javax.jws.soap.SOAPBinding.Style;
  6. import javax.jws.soap.SOAPBinding.Use;
  7. @WebService
  8. @SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
  9. public interface LotteryService {
  10. @WebMethod(operationName = "SendYourNameAndWinLottery")
  11. String sendYourNameAndWinLottery(String nameOfThePerson);
  12. }

LotteryServiceImpl(一种WebService实现):

  1. package org.example.webservice;
  2. import javax.jws.HandlerChain;
  3. import javax.jws.WebService;
  4. @WebService(endpointInterface = "org.example.webservice.LotteryService")
  5. @HandlerChain(file = "custom-fault-message.xml")
  6. public class LotteryServiceImpl implements LotteryService {
  7. @Override
  8. public String sendYourNameAndWinLottery(String nameOfThePerson) {
  9. return "Hi, " + nameOfThePerson + ". You are one of the lucky winners. You won a $1000 USD.";
  10. }
  11. }

注意:您必须通过创建一个具有任意名称的处理程序链.xml文件并将该**. xml**文件设置/引用到@HandlerChain中,来告诉您的WebService使用@HandlerChain
custom-fault-message.xml

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <javaee:handler-chains
  3. xmlns:javaee="http://java.sun.com/xml/ns/javaee"
  4. xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  5. <javaee:handler-chain>
  6. <javaee:handler>
  7. <javaee:handler-class>org.example.handler.CustomizeFaultMessageHandler</javaee:handler-class>
  8. </javaee:handler>
  9. </javaee:handler-chain>
  10. </javaee:handler-chains>

自定义错误消息提示:

  1. package org.example.handler;
  2. import javax.xml.namespace.QName;
  3. import javax.xml.soap.SOAPBody;
  4. import javax.xml.soap.SOAPException;
  5. import javax.xml.soap.SOAPFault;
  6. import javax.xml.ws.handler.MessageContext;
  7. import javax.xml.ws.handler.soap.SOAPHandler;
  8. import javax.xml.ws.handler.soap.SOAPMessageContext;
  9. import java.util.Set;
  10. public class CustomizeFaultMessageHandler implements SOAPHandler<SOAPMessageContext> {
  11. @Override
  12. public boolean handleMessage(SOAPMessageContext context) {
  13. return true;
  14. }
  15. @Override
  16. public boolean handleFault(SOAPMessageContext context) {
  17. try {
  18. SOAPBody body = context.getMessage().getSOAPPart().getEnvelope().getBody();
  19. SOAPFault soapFault = body.getFault();
  20. soapFault.setFaultCode("random-code");
  21. soapFault.setFaultString("place your custom error message here.");
  22. } catch (SOAPException e) {
  23. System.out.println(e.getMessage());
  24. }
  25. return true;
  26. }
  27. @Override
  28. public void close(MessageContext context) {
  29. }
  30. @Override
  31. public Set<QName> getHeaders() {
  32. return null;
  33. }
  34. }

需要注意的一些重要事项:

你必须在handleMessage(SOAPMessageContext context)中从false设置return true;。否则,它不会进入handleFault(SOAPMessageContext context)来处理Fault相关的事情。
现在,你可以看到这样的代码:

  1. SOAPBody body = context.getMessage().getSOAPPart().getEnvelope().getBody();
  2. SOAPFault soapFault = body.getFault();
  3. soapFault.setFaultCode("random-code");
  4. soapFault.setFaultString("place your custom error message here.");


我只是获取默认的Fault,并在这里使用我的自定义Fault CodeFault Message覆盖它。现在,当前的SOAPMessageContext使用包含我的自定义值的Fault进行更新。这就是您需要做的所有事情。

输出(成功案例):
输入XML请求负载:

  1. <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  2. <Body>
  3. <SendYourNameAndWinLottery xmlns="http://webservice.example.org/">
  4. <arg0 xmlns="">Anish</arg0>
  5. </SendYourNameAndWinLottery>
  6. </Body>
  7. </Envelope>

输出XML响应:

  1. <?xml version='1.0' encoding='UTF-8'?>
  2. <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  3. <S:Body>
  4. <ns2:SendYourNameAndWinLotteryResponse xmlns:ns2="http://webservice.example.org/">
  5. <return>Hi, Anish. You are one of the lucky winners. You won a $1000 USD.</return>
  6. </ns2:SendYourNameAndWinLotteryResponse>
  7. </S:Body>
  8. </S:Envelope>


输出(失败,自定义错误消息):

我已经将soap主体名称SendYourNameAndWinLottery篡改为错误的名称SendYourNameAndWin以进行测试。

XML请求负载不正确:

  1. <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  2. <Body>
  3. <SendYourNameAndWin xmlns="http://webservice.example.org/">
  4. <arg0 xmlns="">Anish</arg0>
  5. </SendYourNameAndWin>
  6. </Body>
  7. </Envelope>

输出XML响应:

  1. <?xml version='1.0' encoding='UTF-8'?>
  2. <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  3. <SOAP-ENV:Header/>
  4. <S:Body>
  5. <S:Fault xmlns="" xmlns:ns3="http://www.w3.org/2003/05/soap-envelope">
  6. <faultcode xmlns="">random-code</faultcode>
  7. <faultstring>place your custom error message here.</faultstring>
  8. </S:Fault>
  9. </S:Body>
  10. </S:Envelope>


展开查看全部

相关问题