我正在为我的公司开发一组REST Web服务。我们正在努力解决我们想要使用的技术。 当我使用Jackson JSON提供程序时,我有一个与JAX-RS Jersey 2.6一起使用的模板Web服务,但是当我使用Moxy提供程序时似乎没有正确编组@QueryParam。
搜索可能包含多种“类型”,例如type = keyword& type = product_number& type = fubar 它们映射到包含所有“类型”QueryParam的List类型。当我使用Jackson构建项目时,类型的值被正确地收集到List中,当我使用MOXy时,List为null。 MOXy确实映射了BeanParam中的所有其他Query和Path Params。
问题似乎在于JERSEY是怎样的 当我使用杰克逊时,服务很有效:
http://XXX:8080/SearchTermJersey/search/1/as/wat?type=product_number&type=keyword&count=4&lang=en_US
这是它返回的JSON:
{"autoSuggestions":{"product_number":{"<span>wat</span>21000":34},"keyword":{"<span>wat</span>er":100,"<span>wat</span>er solution":50,"<span>wat</span>er purity":100}},"language":"en_US","requestDate":1393623225135,"responseDate":1393623225135,"term":"wat","version":"1"}
Moxy版本服务的URL返回:
{"language":"en_US","requestDate":1393622174166,"responseDate":1393622174166,"term":"wat","version":"1"}
MOXy和Jackson版本之间的Java代码是相同的 这是BeanParam:
public class AutoSuggestParam {
@PathParam("version")
private String version;
@PathParam("term")
private String term;
private List<String>types;
private Integer count;
String language;
public AutoSuggestParam(@QueryParam("count")int count, @QueryParam("type")List<String>types, @QueryParam("lang")String language) {
this.types = types;
this.count = count;
this.language = language;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getTerm() {
return term;
}
public void setTerm(String term) {
this.term = term;
}
public Integer getCount() {
return count;
}
public String getLanguage() {
return language;
}
public List<String>getTypes() {
return types != null ? types : new ArrayList<String>();
}
问题似乎在于如何处理types参数。使用Jackson,QueryParams类型被正确编组到List中,但MOXy失败并返回null。所以getTypes返回一个空列表。简单的QueryParam计数和lang处理正确。这是泽西岛的一个错误,还是我需要用MOXy做其他事情?
这是我的资源类:
@javax.ws.rs.Path("/search/{version}/as/{term}")
public class AutoSuggestResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public AutoSuggestResponse getAutoSuggest(@BeanParam AutoSuggestParam autoSuggestParam) {
System.out.printf("Request: term=%s version=%s lang=%s type=%s count=%d%n",
autoSuggestParam.getTerm(),autoSuggestParam.getVersion(), autoSuggestParam.getLanguage(), autoSuggestParam.getTypes().get(0), autoSuggestParam.getCount());
return search(autoSuggestParam);
}
private AutoSuggestResponse search(AutoSuggestParam autoSuggestParam) {
AutoSuggestResponse autoSuggestResponse = new AutoSuggestResponse();
autoSuggestResponse.setRequestDate(new Date().getTime());
autoSuggestResponse.setVersion(autoSuggestParam.getVersion());
autoSuggestResponse.setTerm(autoSuggestParam.getTerm());
autoSuggestResponse.setLanguage(autoSuggestParam.getLanguage());
int cnt = 0;
for (String type : autoSuggestParam.getTypes()) {
if ("product_number".equals(type)) {
Map<String, Object> values = autoSuggestResponse.getAutoSuggestions().get(type);
if (values == null) {
values = new LinkedHashMap<String, Object>();
autoSuggestResponse.getAutoSuggestions().put(type, values);
}
String key = String.format("<span>%s</span>21000", autoSuggestParam.getTerm());
values.put(key, 34);
cnt++;
}
else if ("keyword".equals(type)) {
Map<String, Object> values = autoSuggestResponse.getAutoSuggestions().get(type);
if (values == null) {
values = new LinkedHashMap<String, Object>();
autoSuggestResponse.getAutoSuggestions().put(type, values);
}
String key = String.format("<span>%s</span>er", autoSuggestParam.getTerm());
values.put(key, 100);
cnt++;
key = String.format("<span>%s</span>er solution", autoSuggestParam.getTerm());
values.put(key, 50);
cnt++;
key = String.format("<span>%s</span>er purity", autoSuggestParam.getTerm());
values.put(key, 100);
cnt++;
}
if (cnt >= autoSuggestParam.getCount()) {
break;
}
}
autoSuggestResponse.setResponseDate(new Date().getTime());
return autoSuggestResponse;
}
Response类:
public class AutoSuggestResponse {
private Long requestDate;
private Long responseDate;
private String version;
private String term;
private String language;
private Map<String, Map<String,Object>>autoSuggestions = new LinkedHashMap<String, Map<String,Object>>();
public Long getRequestDate() {
return requestDate;
}
public void setRequestDate(Long requestDate ) {
this.requestDate = requestDate;
}
public Long getResponseDate() {
return responseDate;
}
public void setResponseDate(Long responseDate) {
this.responseDate = responseDate;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getTerm() {
return term;
}
public void setLanguage(String language) {
this.language = language;
}
public String getLanguage() {
return language;
}
public void setTerm(String term) {
this.term = term;
}
public Map<String, Map<String,Object>>getAutoSuggestions() {
return autoSuggestions;
}
}
web.xml
<display-name>MoxyAS</display-name>
<servlet>
<servlet-name>MoxyAutoSuggest</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.sial.search.ws</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<servlet-mapping>
<servlet-name>MoxyAutoSuggest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
答案 0 :(得分:0)
默认情况下,EclipseLink JAXB (MOXy)不会封送只有getter的属性。您可以添加@XmlElement
注释以使其成为映射:
@XmlElement
public Map<String, Map<String,Object>>getAutoSuggestions() {
return autoSuggestions;
}
默认情况下,MOXy不使用映射键作为JSON键。以下是解释如何设置的示例的链接:
答案 1 :(得分:0)
我弄明白了这个问题。它与MOXy无关,将genson-0.98.jar添加到路径修复了QueryParam没有在BeanParam中编组的问题。
将@XmlElement添加到资源确实使Moxy工作了。如果我将XmlElement添加到Response类中的Map,我现在会收到错误: javax.servlet.ServletException:org.glassfish.jersey.server.ContainerException:java.lang.NoClassDefFoundError:org / eclipse / persistence / internal / libraries / asm / ClassWriter
但这是一个新问题。