我有一个使用wsimport
(在ANT任务中)生成的Web服务,我想要处理我发送无效XML请求时出现的javax.xml.bind.UnmarshalException
异常。
为了抛出这个异常,我只是向服务器发送一个不平衡的标签,然后我回来了:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>javax.xml.bind.UnmarshalException
- with linked exception:
[com.ctc.wstx.exc.WstxParsingException: Unexpected close tag </m:BAR>; expected </m:BR>.
at [row,col {unknown-source}]: [16,38]]</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>
不幸的是,在我的代码中,我看不到捕获此异常并发送回标准消息的方法,而不是自动发送客户端可能无法解析的一些webservice-internal异常。
有没有办法告诉JAX-W在生产或开发模式下运行?在生产模式下,它会允许我覆盖发送的消息以回复错误的请求吗?
或者至少实现某种钩子,当JAX-WS的代码发生异常时,它会调用我的方法......
我正在Glassfish 4.1.2上运行该服务。
用于构建wsdl
的Web服务的我的ANT脚本如下所示:
<!DOCTYPE project>
<project name="WSDL to Java generator" default="wsimport">
<path id="wsimport.classpath">
<fileset dir="../../EAR/EarContent/lib">
<include name="commons-beanutils-*.jar"/>
<include name="commons-lang-*.jar"/>
<include name="commons-logging-*.jar"/>
</fileset>
<fileset dir="../../Common/ant-libs">
<include name="*.jar"/>
</fileset>
</path>
<taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport" classpathref="wsimport.classpath"/>
<target name="wsimport">
<wsimport verbose="true" wsdl="../schemas/WebService.wsdl" wsdlLocation="../schemas/WebService.wsdl" binding="./ws-build-bindings.xjb">
<xjcarg line="-Xannotate"/>
<xjcarg line="-Xinheritance"/>
<arg line="-keep"/>
<arg line="-d ../src"/>
<arg line="-p org.company.name.message"/>
<arg line="-Xnocompile"/>
</wsimport>
</target>
</project>
生成的界面如下所示:
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.Holder;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.3.0
* Generated source version: 2.2
*
*/
@WebService(name = "WebService", targetNamespace = "http://company.com/foo/WebService/")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({
ObjectFactory.class
})
public interface WebService {
@WebMethod(operationName = "PublishEvent", action = "PublishEvent")
@WebResult(name = "ResponseMessage", targetNamespace = "http://foo.bar/schema/message", partName = "response")
public ResponseMessageType publishEvent(
@WebParam(name = "EventMessage", targetNamespace = "http://foo.bar/schema/message", partName = "event")
EventMessageType event);
@WebMethod(operationName = "Request", action = "Request")
@WebResult(name = "ResponseMessage", targetNamespace = "http://foo.bar/schema/message", partName = "response")
public ResponseMessageType request(
@WebParam(name = "RequestMessage", targetNamespace = "http://foo.bar/schema/message", partName = "request")
RequestMessageType request);
@WebMethod(operationName = "Response", action = "Response")
public void response(
@WebParam(name = "ResponseMessage", targetNamespace = "http://foo.bar/schema/message", mode = WebParam.Mode.INOUT, partName = "response")
Holder<ResponseMessageType> response);
}
生成的类Service
:
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.3.0
* Generated source version: 2.2
*
*/
@WebServiceClient(name = "WebService", targetNamespace = "http://company.com/foo/WebService/", wsdlLocation = "../schemas/WebService.wsdl")
public class WebService_Service
extends Service
{
private final static URL WebSERVICE_WSDL_LOCATION;
private final static WebServiceException WebSERVICE_EXCEPTION;
private final static QName WebSERVICE_QNAME = new QName("http://company.com/foo/WebService/", "WebService");
static {
WebSERVICE_WSDL_LOCATION = org.company.name.message.WebService_Service.class.getResource("../schemas/WebService.wsdl");
WebServiceException e = null;
if (WebSERVICE_WSDL_LOCATION == null) {
e = new WebServiceException("Cannot find '../schemas/WebService.wsdl' wsdl. Place the resource correctly in the classpath.");
}
WebSERVICE_EXCEPTION = e;
}
public WebService_Service() {
super(__getWsdlLocation(), WebSERVICE_QNAME);
}
public WebService_Service(WebServiceFeature... features) {
super(__getWsdlLocation(), WebSERVICE_QNAME, features);
}
public WebService_Service(URL wsdlLocation) {
super(wsdlLocation, WebSERVICE_QNAME);
}
public WebService_Service(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, WebSERVICE_QNAME, features);
}
public WebService_Service(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public WebService_Service(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
@WebEndpoint(name = "WebServiceSOAP")
public WebService getWebServiceSOAP() {
return super.getPort(new QName("http://company.com/foo/WebService/", "WebServiceSOAP"), WebService.class);
}
@WebEndpoint(name = "WebServiceSOAP")
public WebService getWebServiceSOAP(WebServiceFeature... features) {
return super.getPort(new QName("http://company.com/foo/WebService/", "WebServiceSOAP"), WebService.class, features);
}
private static URL __getWsdlLocation() {
if (WebSERVICE_EXCEPTION!= null) {
throw WebSERVICE_EXCEPTION;
}
return WebSERVICE_WSDL_LOCATION;
}
}
这是我对界面的实现(省略了实际工作的代码),当发出无效请求时,我无法抓住它,因为我的方法不是称为:
import javax.jws.WebService;
import javax.xml.ws.Holder;
import org.company.name.message.ErrorType.ErrorLevelEnum;
import org.company.name.message.EventMessageType;
import org.company.name.message.HeaderType;
import org.company.name.message.WebService;
import org.company.name.message.RequestMessageType;
import org.company.name.message.ResponseMessageType;
@WebService(endpointInterface = "org.company.name.message.WebService")
public class Web implements WebService {
@Override
public ResponseMessageType publishEvent(EventMessageType event) {
ResponseMessageBuilder responseBuilder = new ResponseMessageBuilder();
try
{
// build response here
}
catch (WebException exception) {
// error building response
}
catch (Exception ex) {
// general error
}
return responseBuilder.build();
}
@Override
public ResponseMessageType request(RequestMessageType request) {
ResponseMessageBuilder responseBuilder = new ResponseMessageBuilder();
try
{
// build response here
}
catch (WebException exception) {
// error building response
}
catch (Exception ex) {
// general error
}
return responseBuilder.build();
}
@Override
public void response(Holder<ResponseMessageType> response) {
// TODO Auto-generated method stub
}
}
答案 0 :(得分:0)
使用<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.journaldev.tablayoutappbar.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay" />
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
app:tabGravity="fill"
app:tabMode="fixed"
android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sample_text"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
(https://docs.oracle.com/middleware/1213/wls/WSGET/jax-ws-soaphandlers.htm#WSGET3446)修复此问题。
处理程序拦截请求,尝试SOAPHandler
它(通过JAXB)并且如果抛出异常,我自定义响应消息(即通过unmarshal
完全替换它messageContext.setMessage(soapFaultMessage);
1}} handleMessage
的方法并将其发回(通过从SOAPHandler
方法返回false
。
此外,值得研究一下你可以抛出的handleMessage
类(https://docs.oracle.com/javase/7/docs/api/javax/xml/ws/soap/SOAPFaultException.html),并根据自己的喜好定制肥皂故障响应信息。