Java: JAX-WS Mapping

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

Всякий раз, когда я использую параметр char в качестве параметра метода, я получаю его как 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 или что-то еще?

Ответ 1

Обновление:

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

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

Но я думаю, что вопрос заключается в контракте last (например, писать код, который генерирует 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 char любым другим способом, а char действительно является беззнаковым коротким, и самое близкое, что вы можете ограничить до 1 "String" char.

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

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

Ответ 3

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

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, вам придется обрабатывать нуль.

UPDATE EDIT: я не думаю, что вы можете указать длину строки с этим, но без ручного создания/редактирования 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>

Ответ 4

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