0

私は Java Web サービスに不慣れで、過去 4 日間この問題に悩まされています。ここに問題があります。他のアプリケーションで使用する Web サービスを作成するつもりです。要件は、Web サービスがテーブルから複数のレコードを返す必要があるため、サンプル Web サービスを作成しました。コードは次のとおりです。

インターフェース

@WebService 
@SOAPBinding(style = Style.DOCUMENT)
public interface TestClassInt {

/**
 * @param args
 */

@WebMethod
SampleClass[] getCaseId (String country);
}

2 つの文字列オブジェクトを持つカスタム クラス

public class SampleClass {
protected String caseid;
protected String dummy;

public SampleClass(){
    super();
}
public SampleClass(String caseid,String dummy){
    this.caseid=caseid;
    this.dummy=dummy;
}
public String getDummy() {
    return dummy;
}

public void setDummy(String dummy) {
    this.dummy = dummy;
}

public String getCaseid() {
    return caseid;
}

public void setCaseid(String caseid) {
    this.caseid = caseid;
}
}

そして、ここに実装があります

@WebService(endpointInterface = "com.org.ccb.test.TestClassInt")
public class TestClassImpl implements TestClassInt {

public SampleClass[] getCaseId(String country) {
    // TODO Auto-generated method stub
    System.out.println("Console " + country);
    SampleClass tempSc[] = new SampleClass[2];
    tempSc[0]=new SampleClass();
    tempSc[1]=new SampleClass();
    tempSc[0].setCaseid(country);
    tempSc[0].setDummy(country);
    tempSc[1].setCaseid(country);
    tempSc[1].setDummy(country);
    return tempSc;
}

}

JBoss Developer Studio を使用して生成された WSDL は、

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="TestClassImplService targetNamespace="http://test.ccb.org.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://test.ccb.org.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://test.ccb.org.com/" targetNamespace="http://test.ccb.org.com/" version="1.0">
<xs:element name="getCaseId" type="tns:getCaseId"/>
<xs:element name="getCaseIdResponse" type="tns:getCaseIdResponse"/>
<xs:complexType name="getCaseId">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getCaseIdResponse">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="sampleClass" type="tns:sampleClass"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sampleClass">
<xs:sequence>
<xs:element maxOccurs="1" name="caseid" type="xs:string"/>
<xs:element maxOccurs="1" name="dummy" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="getCaseIdResponse">
<wsdl:part name="parameters" element="tns:getCaseIdResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getCaseId">
<wsdl:part name="parameters" element="tns:getCaseId">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="TestClassInt">
<wsdl:operation name="getCaseId">
  <wsdl:input name="getCaseId" message="tns:getCaseId">
</wsdl:input>
  <wsdl:output name="getCaseIdResponse" message="tns:getCaseIdResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestClassImplServiceSoapBinding" type="tns:TestClassInt">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getCaseId">
  <soap:operation soapAction="" style="document"/>
  <wsdl:input name="getCaseId">
    <soap:body use="literal"/>
  </wsdl:input>
  <wsdl:output name="getCaseIdResponse">
    <soap:body use="literal"/>
  </wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TestClassImplService">
<wsdl:port name="TestClassImplPort" binding="tns:TestClassImplServiceSoapBinding">
  <soap:address location="http://localhost:8080/rc_ccb/TestClass"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

SOAP リクエストを受け取ると、キャスト例外が発生します [Lcom.org.ccb.test.SampleClass; com.org.ccb.test.SampleClass にキャストできません

Web サービスからオブジェクトの配列を取得する場合、WSDL の定義は次のとおりですよね?

<xs:complexType name="getCaseIdResponse">  
<xs:sequence>  
<xs:element maxOccurs="unbounded" name="sampleClass" type="tns:sampleClass"/>  
</xs:sequence>  
</xs:complexType>  
<xs:complexType name="sampleClass">  
<xs:sequence>  
<xs:element maxOccurs="1" name="caseid" type="xs:string"/>  
<xs:element maxOccurs="1" name="dummy" type="xs:string"/>  
</xs:sequence>  
</xs:complexType>

サーバー: JBoss eap 5.1

何か案が?

スタックトレース

14:31:46,743 WARNING [PhaseInterceptorChain] Interceptor for {http://test.ccb.org.com  /}TestClassImplService#{http://test.ccb.org.com/}getCaseId has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: [Lcom.org.ccb.test.SampleClass; cannot be cast to   com.org.ccb.test.SampleClass
at   org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:119)
at  org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:76)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:109)
at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:98)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:406)
at org.jboss.wsf.stack.cxf.ServletControllerExt.invoke(ServletControllerExt.java:173)
at org.jboss.wsf.stack.cxf.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:61)
at org.jboss.wsf.stack.cxf.CXFServletExt.invoke(CXFServletExt.java:163)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:183)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:95)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:451)
at java.lang.Thread.run(Thread.java:662)
  Caused by: java.lang.ClassCastException: [Lcom.org.ccb.test.SampleClass; cannot be cast to com.org.ccb.test.SampleClass
at   com.org.ccb.test.jaxws.GetCaseIdResponse_WrapperTypeHelper1.createWrapperObject(Unknown Source)
at  org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:103)
... 33 more

**主要な編集** Create Web Serviceウィザードはesdlファイルを生成しましたが、 maxOccurs="unbounded" が含まれていなかったため、手動で追加、保存、再起動したところ、変更されると思っていましたが、wsdlが変更されていないことがわかりました古いものを保持しているので、問題になるはずです!wsdl ファイルが変更されない理由が見つかりませんでした!

4

3 に答える 3

0

wsdl を編集するボトムアップ サービスは無駄だったので、(JBoss Studio を使用して) wsdl から Java スケルトン クラスを生成し、実装クラスにビジネスを記述しました。現在、サービスは正常に機能しています。とにかくmaxOccurs="unbounded"、wsdlが最初にJavaクラスから生成されたときに、なぜ自動的に生成されなかったのかわかりません。返信ありがとう@gkzmin @mhan @dan

于 2012-08-22T06:36:10.257 に答える
0

少し高度な概念を理解する必要があります。

http://weblogs.java.net/blog/kohsuke/archive/2005/04/xmladapter_in_j.html

http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html

http://docs.oracle.com/javaee/5/tutorial/doc/bnazf.html

これを行う方法は、テーブル/エンティティを表すクラスを取得することです。次に、list_of_entities のラッパー クラスがあります。これは Web サービスからの戻り値です。したがって、合計:

  1. 必要なアノテーションを含むエンティティ クラス
  2. 必要な注釈を含むラッパー クラス
  3. 必要なアノテーションを含む Web サービス

以下にこれらのそれぞれのサンプルを提供しましたが、実行されない可能性があります。それらはあなたに理解を与えるためのものです。

//*********************** 1. your Object/Structure/table record you want to return

//since you'll like to send the object across thus it should be serializable
import java.io.Serializable;

//The following two imports are specific to your case. Read about them
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

//The code related to the following classes is just to give you a taster of the JPA side of it
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Entity;


/**
 *  The class that will be the Type of your list, I have used it as an entity too for the JPA Layer
 *
 */
@XmlType(namespace = "myNamespace")

@Entity
@Table(name="MY_TABLE"
    ,schema="MY_DB_SCHEMA"
)

public class SampleClass implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1L;
protected String caseid;
protected String dummy;
/**
 * @return the dummy
 */
@XmlElement(namespace = "myNamespace")
@Column(name="TYPE", nullable=true, length=225) 
public String getDummy() {
    return dummy;
}
/**
 * @return the caseid
 */
@Id
@Column(name="TYPE", nullable=false, length=225)


@XmlElement(namespace = "myNamespace")

public String getCaseid() {
    return caseid;
}
/**
 * @param caseid the caseid to set
 */
public void setCaseid(String caseid) {
    this.caseid = caseid;
}
/**
 * @param dummy the dummy to set
 */
public void setDummy(String dummy) {
    this.dummy = dummy;
}

}

// * ** * ** * ** * ***2. オブジェクト ラッパー クラス** * ** * ** * ** * ****

// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.1-b02-fcs 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2009.02.12 at 12:55:08 PM GMT 
//
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

import YOURPACKAGE.SampleClass;

/**
 * Wrapper class for List, makes it possible for JAXB to marshal/unmarshal java.util.List.
 * 
 * @param <T>
 *          Generic List
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "myListType", propOrder = { "listReturn" })
public class ExampleList {

  /**
   * instructing JAXB about the xml element and the name to use in the resulting xml structure.
   */
  @XmlElement(name = "sampleClass")
  protected List<SampleClass> listReturn;

  public ExampleList() {
    listReturn = new ArrayList<SampleClass>();
  }

  /**
   * @param local_list
   *          a generic list
   */
  public ExampleList(final List<SampleClass> local_list) {
    listReturn = local_list;
  }

  public List<SampleClass> getList() {
    return listReturn;
  }

}

// * ** * ** * ** * ** * ** * *

// * ** * ** * ***3. ウェブサービス** * ** * ** * ** *

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;



@Stateless(name = "myEJB")
@WebService(serviceName = "myService", targetNamespace = "mynamespace", name = "myServicePT", portName = "myServicePort")
public class ServiceImpl implements ServiceLocal {

  @SuppressWarnings("unused")
  private final Log log = LogFactory.getLog(ServiceImpl.class);

  @PersistenceContext(name = "MyContext")
  private EntityManager em;


  @WebMethod(operationName = "listAll")
  @WebResult(name = "myList", targetNamespace = "mynamespace")
  public ExampleList listAll() throws EastException {
    try {
      Query query = em.createNamedQuery("myQueryToGetMyListFromDB");
      return new ExampleList(query.getResultList());
    }
    catch (Exception e) {
      log.error("Error in retrieving  list", e);

    }
  }



}

// * ** * ***3.1 Web サービスのローカル インターフェイス* ** * ****

import javax.ejb.Local;

@Local
public interface ServiceLocal {
    ExampleList listAll();
}

// * ** * ** * ** * ** * ** * ** * ** * ****

于 2012-08-21T11:20:54.363 に答える
0

JBoss で生成された WSDL ファイルが間違っていると思われ、次のコード

<xs:complexType name="getCaseId">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
</xs:sequence>
</xs:complexType>

このように見えるはずです

<xs:complexType name="getCaseId">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="arg0" type="xs:string"/>
</xs:sequence>
</xs:complexType>

デフォルトmaxOccursの属性値は 1 で、の配列はSimpleClass単一のインスタンスになり、SingleClassクラス キャスト エラーが発生します (配列をインスタンスにキャストしようとしています)。

私はJBossスタジオの経験がありませんが、配列の代わりにコレクションを使用することを提案できます.JBossは配列よりもコレクションをうまく処理できるかもしれません. また、JAX-WS を試すこともできます。

于 2012-08-21T08:57:22.020 に答える