Java: сопоставление JAX-WS - PullRequest
       28

Java: сопоставление JAX-WS

11 голосов
/ 31 августа 2011

Я использую JAX-WS для веб-сервисов.

Каждый раз, когда я использую символ в качестве параметра метода, я получаю его как unsignedShort в xsd (Focus on weatherLetter).

Вот декларация:

@WebMethod
public boolean setWXtatus(
        @WebParam(name = "weatherLetter") char weatherLetter,
        @WebParam(name = "weatherDigit") int weatherDigit,
        @WebParam(name = "cloudCover") int cloudCover,
        @WebParam(name = "cloudBaseInHundredsOfFeet") int cloudBaseInHundredsOfFeet,
        @WebParam(name = "pressureInHg") int pressureInHg,
        @WebParam(name = "visibilityInKm") int visibilityInKm,
        @WebParam(name = "windSpeed") int windSpeed,
        @WebParam(name = "windDirection") int windDirection,
        @WebParam(name = "lastUpdateHour") int lastUpdateHour,
        @WebParam(name = "lastUpdateMin") int lastUpdateMin
) 

Вот сопоставления типов, которые я получаю:

<xs:complexType name="setWXStatus">
<xs:sequence>
<xs:element name="weatherLetter" type="xs:unsignedShort" minOccurs="0"/>
<xs:element name="weatherDigit" type="xs:int"/>
<xs:element name="cloudCover" type="xs:int"/>
<xs:element name="cloudBaseInHundredsOfFeet" type="xs:int"/>
<xs:element name="pressureInHg" type="xs:int"/>
<xs:element name="visibilityInKm" type="xs:int"/>
<xs:element name="windSpeed" type="xs:int"/>
<xs:element name="windDirection" type="xs:int"/>
<xs:element name="lastUpdateHour" type="xs:int"/>
<xs:element name="lastUpdateMin" type="xs:int"/>
</xs:sequence>
</xs:complexType>

Как я могу заставить WeatherLetter генерировать как Char или 1 Letter String или что-то еще?

Ответы [ 4 ]

10 голосов
/ 02 сентября 2011

Обновление:

Один из способов сделать это - XSD (если вы сначала заключаете контракт ), например. добавьте XSD Restriction непосредственно к нему, например,

<xs:element name="singleChar">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:length value="1"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

Но я думаю, что вопрос о контракте последний (например, написать код, который генерирует XSD, а не наоборот)

Насколько я знаю, это еще не поддерживается в JAX-WS или JAXB (но хороший запрос на улучшение)

Источники:

JAX-WS и JAXB не поддерживают генерацию кода для ограничений из XSD (например, xsd: ограничение) http://old.nabble.com/Does-jaxb-2.1-enforce-xs:restriction-td21348458.html

Причина в том, что другое направление (создание ограничений посредством аннотации) тоже не поддерживается

Обход:

Взгляните на это: http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html

А также на этот вопрос:

JAX-WS и Joda-Time?

Не делает именно то, что вы хотите, но приближает вас немного


Я не думаю, что вы можете ограничить его до 1 символа любым другим способом, символ действительно является неподписанным коротким, и самое близкое, что вы можете ограничить 1 символом "String".

Если вы используете строку, вы разрешите неограниченное количество символов. и @ WebParam не имеет API для ограничения длины

На самом деле я вообще не видел способа сделать ограничения XSD с помощью JAX-WS, но я могу ошибаться

5 голосов
/ 02 сентября 2011

Используйте адаптер, что-то вроде:

import javax.xml.bind.annotation.adapters.XmlAdapter;


public class CharAdapter extends XmlAdapter<String, Character> {

    @Override
    public String marshal(Character c) throws Exception
    {
        return String.valueOf(c);
    }

    @Override
    public Character unmarshal(String s) throws Exception
    {
    if(s == null) {
        return null;
    }
    if(s.length() != 1) {
        throw new IllegalArgumentException("Provided string \"" + s + 
                "\" has invalid length of " + s.length() + " should be 1");
    }
        return s.charAt(0);
    }

}

А затем в вашем WXStatus (определите один класс в качестве входного аргумента вместо передачи множества отдельных параметров - JAX уже превращает это в complexTypeтак что вы можете также, плюс это лучший стиль ООП), добавить эту аннотацию (либо к полю, либо к получателю):

@XmlJavaTypeAdapter(CharAdapter.class)
char weatherLetter;

Это позволит un / marshalling на вашей стороне сервера, и клиент увидитэто как строка xs:Одним из побочных эффектов является то, что мы используем примитивную оболочку для char, вам придется обрабатывать null.

ОБНОВЛЕНИЕ РЕДАКТИРОВАНИЯ: Я не думаю, что есть какой-либо способ указать длину строки с помощью этогобез создания / редактирования вашего WSDL вручную, например:

<xs:simpleType name="weatherLetter">
  <xs:annotation>
    <xs:documentation>weather character info blah blah</xs:documentation>
  </xs:annotation>
  <xs:restriction base="xs:string">
    <xs:length value="1"/>
  </xs:restriction>
</xs:simpleType>
5 голосов
/ 02 сентября 2011

char и java.lang.Character требуют ввода пользовательских сопоставлений, так как сопоставления по умолчанию из char или java.lang.Character в WSDL XSD не существуют.

Цитируется по http://publib.boulder.ibm.com/infocenter/radhelp/v6r0m1/index.jsp?topic=%2Fcom.ibm.etools.webservice.creation.doc%2Fconcepts%2Fcsoaptover.html

1 голос
/ 02 сентября 2011

Вы должны попробовать изменить его с char на String в вашем объявлении, если вы хотите получить только один символ, если вы программируете клиентскую часть, не должно быть особых проблем с этим

...