如何使用 jersey-media-moxy map/convert 嵌套参数?
How to map/convert nested params with jersey-media-moxy?
我正在使用 jersey 和 MOXy 编写一个 RESTful Web 应用程序,以支持基于 JSON 的 JAXB。
我的目标是使用 POJO 作为使用 JSON 的方法参数。
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void postRequest(MyPOJO myPOJO) {
System.out.println(myPOJO.name);
System.out.println(myPOJO.currency);
}
这个 POJO 有一个字符串成员和一个 java.util.Currency 类型的成员。
@XmlRootElement
public class MyPOJO {
public String name;
public Currency currency;
public MyPOJO() {};
}
我还有一个自定义的 Currency ParamConverter(和 Provider),见下文。有了这个,我能够正确处理 Currency 类型的 QueryParam。
但是如果我通过 POST 使用以下内容查询我的资源 JSON 内容货币未映射并且在正确映射名称时将为空。
{ "name": "peter", "currency": "EUR" }
控制台输出结果为:
peter
null
我还需要做什么来告诉 MOXy 正确映射这个嵌套对象成员?
这是我的货币 ParamConverter:
@Provider
public class CurrencyParamConverterProvider implements ParamConverterProvider {
@Override
public <T> ParamConverter<T> getConverter(final Class<T> rawType, Type genericType, Annotation[] annotations) {
return rawType != Currency.class ? null : new ParamConverter<T>() {
@Override
public T fromString(String value) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.METHOD_PARAMETER_CANNOT_BE_NULL("value"));
}
try {
return rawType.cast(Currency.getInstance(value));
} catch (IllegalArgumentException e) {
throw new ExtractorException("Currency must be a valid ISO 4217 code of the currency.", e);
}
}
@Override
public String toString(T value) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.METHOD_PARAMETER_CANNOT_BE_NULL("value"));
}
return value.toString();
}
};
}
}
Currency
是一个对象,所以在JSON的世界里,应该是
{ "name": "peter", "currency": { "fieldName" :"EUR"} }
您没有收到任何失败通知的原因是默认情况下 MOXy 只是意味着忽略这些类型的 missing/unknown 属性 问题。
解决这个问题的一种方法是使用 XmlAdapter
。例如
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class CurrencyAdapter extends XmlAdapter<String, Currency>{
@Override
public Currency unmarshal(String v) throws Exception {
Currency c = new Currency();
c.type = v;
return c;
}
@Override
public String marshal(Currency v) throws Exception {
return v.type;
}
}
其中 Currency.type
只是保存 "EUR"
值的字段。然后你只需要用适配器
注释property/field
@XmlRootElement
public class MyPojo {
public String name;
@XmlJavaTypeAdapter(CurrencyAdapter.class)
public Currency currency;
}
我正在使用 jersey 和 MOXy 编写一个 RESTful Web 应用程序,以支持基于 JSON 的 JAXB。
我的目标是使用 POJO 作为使用 JSON 的方法参数。
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void postRequest(MyPOJO myPOJO) {
System.out.println(myPOJO.name);
System.out.println(myPOJO.currency);
}
这个 POJO 有一个字符串成员和一个 java.util.Currency 类型的成员。
@XmlRootElement
public class MyPOJO {
public String name;
public Currency currency;
public MyPOJO() {};
}
我还有一个自定义的 Currency ParamConverter(和 Provider),见下文。有了这个,我能够正确处理 Currency 类型的 QueryParam。
但是如果我通过 POST 使用以下内容查询我的资源 JSON 内容货币未映射并且在正确映射名称时将为空。
{ "name": "peter", "currency": "EUR" }
控制台输出结果为:
peter
null
我还需要做什么来告诉 MOXy 正确映射这个嵌套对象成员?
这是我的货币 ParamConverter:
@Provider
public class CurrencyParamConverterProvider implements ParamConverterProvider {
@Override
public <T> ParamConverter<T> getConverter(final Class<T> rawType, Type genericType, Annotation[] annotations) {
return rawType != Currency.class ? null : new ParamConverter<T>() {
@Override
public T fromString(String value) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.METHOD_PARAMETER_CANNOT_BE_NULL("value"));
}
try {
return rawType.cast(Currency.getInstance(value));
} catch (IllegalArgumentException e) {
throw new ExtractorException("Currency must be a valid ISO 4217 code of the currency.", e);
}
}
@Override
public String toString(T value) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.METHOD_PARAMETER_CANNOT_BE_NULL("value"));
}
return value.toString();
}
};
}
}
Currency
是一个对象,所以在JSON的世界里,应该是
{ "name": "peter", "currency": { "fieldName" :"EUR"} }
您没有收到任何失败通知的原因是默认情况下 MOXy 只是意味着忽略这些类型的 missing/unknown 属性 问题。
解决这个问题的一种方法是使用 XmlAdapter
。例如
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class CurrencyAdapter extends XmlAdapter<String, Currency>{
@Override
public Currency unmarshal(String v) throws Exception {
Currency c = new Currency();
c.type = v;
return c;
}
@Override
public String marshal(Currency v) throws Exception {
return v.type;
}
}
其中 Currency.type
只是保存 "EUR"
值的字段。然后你只需要用适配器
@XmlRootElement
public class MyPojo {
public String name;
@XmlJavaTypeAdapter(CurrencyAdapter.class)
public Currency currency;
}