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, но я могу ошибаться
Ответ 2
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
Ответ 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 в объявлении, если вы хотите получить только один символ, если вы программируете клиентскую сторону, не должно быть особых проблем при этом