[JAVA] Spring, XFire en Annotations probleem

Pagina: 1
Acties:

  • licensed
  • Registratie: Augustus 2002
  • Laatst online: 20-05-2024
Om wat ervaring met Web Services in Spring en XFire op te doen heb ik een service gemaakt waarmee je Patient Records aan kan maken en op kan vragen. Dit werkt op zich hartstikke mooi, maar er is één probleem, het opslaan van de zipcode (int) en birthday (Date) gaat niet goed.

De service is dus geïmplementeerd met Spring en XFire en heeft de volgende package structuur:

src
+ -- dao
+ -- service
+ -- types
+ -- utility
+ -- vo

De service interface en implementatie staan in de service package, de Patient class staat in types.

Patient:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package types;

import java.util.Date;

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


/**
 * <p>Java class for Patient complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="Patient">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="patID" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         &lt;element name="patName" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         &lt;element name="patStreet" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         &lt;element name="patZipCode" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *         &lt;element name="patCity" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         &lt;element name="patBirthday" type="{http://www.w3.org/2001/XMLSchema}date"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Patient", propOrder = {
    "patID",
    "patName",
    "patStreet",
    "patZipCode",
    "patCity",
    "patBirthday"
})
public class Patient {

    @XmlElement(required = true)
    protected String patID;
    @XmlElement(required = true)
    protected String patName;
    @XmlElement(required = true)
    protected String patStreet;
    @XmlElement(required = true)  
    protected int patZipCode;
    @XmlElement(required = true)
    protected String patCity;
    @XmlElement(required = true)
    protected Date patBirthday;

    public String getPatID() {
        return patID;
    }

    public void setPatID(String value) {
        this.patID = value;
    }

...

    public void setPatBirthday(Date value) {
        this.patBirthday = value;
    }

}


en de ElectronicPatientRecord interface:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package service;

import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

import types.Patient;
import types.PatientList;

@WebService(name = "ElectronicPatientRecord", targetNamespace = "http://www.PAHospital.org/PatService/")
@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ElectronicPatientRecord {

    @WebMethod(operationName = "create_PatientRecord", action = "http://www.PAHospital.org/PatService/create_PatientRecord")
    @Oneway
    public void create_PatientRecord(
        @WebParam(name = "patient", targetNamespace = "http://www.PAHospital.org/PatService/")
        Patient patient);


    @WebMethod(operationName = "get_PatientsByName", action = "http://www.PAHospital.org/PatService/get_PatientsByName")
    @WebResult(name = "pList", targetNamespace = "http://www.PAHospital.org/PatService/")
    public PatientList get_PatientsByName(
        @WebParam(name = "pName", targetNamespace = "http://www.PAHospital.org/PatService/")
        String pName);

}


De cliënt heb ik vervolgens in C# geschreven mbv Visual Studio. Bij het aanmaken van de web reference geeft VS de volgende Warning:
Warning 2 Custom tool warning: Schema validation warning: Schema item 'element' named 'create_PatientRecord' from namespace 'http://www.PAHospital.org/PatService/' is invalid. Namespace 'http://types' is not available to be referenced in this schema. C:\...\Visual Studio 2005\Projects\PatServiceClient\PatServiceClient\Properties\Settings.settings 1 1

Maar in de package types staat een package-info.java:
Java:
1
2
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.PAHospital.org/PatService/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = {@javax.xml.bind.annotation.XmlNs(prefix="xsd", namespaceURI="http://www.w3.org/2001/XMLSchema")})
package types;


Dus waar komt die namespace http://types vandaan??

De gegenereerde WSDL ziet er zo uit:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...

  <wsdl:types>
    <xsd:schema targetNamespace="http://types" elementFormDefault="qualified" attributeFormDefault="qualified">

...

      <xsd:complexType name="Patient">
        <xsd:sequence>
          <xsd:element name="patBirthday" type="xsd:dateTime" minOccurs="0"/>
          <xsd:element name="patCity" type="xsd:string" minOccurs="0" nillable="true"/>
          <xsd:element name="patID" type="xsd:string" minOccurs="0" nillable="true"/>
          <xsd:element name="patName" type="xsd:string" minOccurs="0" nillable="true"/>
          <xsd:element name="patStreet" type="xsd:string" minOccurs="0" nillable="true"/>
          <xsd:element name="patZipCode" type="xsd:int" minOccurs="0"/>
        </xsd:sequence>
      </xsd:complexType>

...


Het lijkt dus wel of de annotaties niet meegenomen worden want minOccurs zou de waarde 1 moeten hebben :?

Waardoor wordt dit veroorzaakt? Hoe zorg ik ervoor dat ook niet String waarden meegegeven kunnen worden??

Aan de configuratie ligt het volgens mij niet.
web.xml:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
    <display-name>Electronic Patient Record</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext-jdbc.xml
      ,/WEB-INF/applicationContext-dao.xml
      ,/WEB-INF/applicationContext-service.xml
      ,/WEB-INF/xfire-servlet.xml</param-value>
    </context-param>
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>
    
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <servlet>
        <servlet-name>XFireServlet</servlet-name>  
        <servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping> 
        <servlet-name>XFireServlet</servlet-name> 
        <url-pattern>/servlet/XFireServlet/*</url-pattern> 
    </servlet-mapping>
    <servlet-mapping> 
        <servlet-name>XFireServlet</servlet-name> 
        <url-pattern>/services/*</url-pattern> 
    </servlet-mapping>

</web-app>


xfire-servlet.xml:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="jsr181WebAnnotations" class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"/>
        
    <bean id="xfireHandlerMapping" class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping">
        <property name="typeMappingRegistry">
            <ref bean="xfire.typeMappingRegistry"/>
        </property>
        <property name="xfire">
            <ref bean="xfire"/>
        </property>
        <property name="webAnnotations">
            <ref bean="jsr181WebAnnotations"/>
        </property>
    </bean>

    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
        <property name="urlMap"> 
            <map> 
                <entry key="/"> 
                    <ref bean="xfireHandlerMapping"/>
                </entry> 
            </map> 
        </property> 
    </bean>

    <import resource="classpath:org/codehaus/xfire/spring/xfire.xml"/>
</beans>


Ik hoop dat iemand me op weg kan helpen.

  • Dnomaid
  • Registratie: Augustus 2003
  • Laatst online: 01-12 10:52
Aiaiai, ik ben net naar hetzelfde op zoek!

Deze bug belooft alvast niet veel goeds:
http://jira.codehaus.org/browse/XFIRE-825

Ik weet dat het hierbij puur om de settings gaat en niet om de annotations, maar het problem is hetzelfde.

Het lijkt erop dat de returntypes, hoe je ook je best doet, zowiezo in de namespace van de package terechtkomen. En dan bedoel ik dus dat de namespace wordt gevormd naar jou packagestructuur, en dat er naar niks anders gekeken wordt (settings / annotations).

Duidelijk een bug in XFire dus, hopen dat dit snel opgelost wordt!

[ Voor 36% gewijzigd door Dnomaid op 09-03-2007 16:27 ]


  • Dnomaid
  • Registratie: Augustus 2003
  • Laatst online: 01-12 10:52
Na wat verder onderzoek te hebben gedaan en wat contactpersonen te hebben geraadpleegd, kan ik je het volgende zeggen.

De bug waar we beiden last van hebben zou veroorzaakt worden door de Aegis XML binding die XFire standaard gebruikt. Morgen ga ik proberen de JAXB binding te gebruiken, als dat werkt laat ik nog wel iets weten.

  • Dnomaid
  • Registratie: Augustus 2003
  • Laatst online: 01-12 10:52
Hoi licensed!

Ondertussen nog veel tijd in gestoken, hier is mijn conclusie:
De annotations die jij importeert zijn geschikt voor jaxb, xfire ondersteunt die standaard allemaal niet. Ik gebruik nu de Aegis set, die is heel wat beperkter, maar die reageert dan wel gewoon hoe het moet op de annotations.

Ik heb begrepen dat, wil je die jaxb-annotations gebruiken, je de jaxb-binding van xfire moet gebruiken. En laat dat nu net eens iets zijn dat ik niet geconfigureerd krijg: alles wat ik vind gaat over xfire en spring, of xfire en jaxb. Een heldere combinatie van de drie heb ik nog niet gezien, en krijg ik dus ook niet opgezet.

Mvg.