【问题标题】:Jersey 2.6 @QueryParam is missing from @BeanParam when using MOXY but not with JacksonJersey 2.6 @QueryParam 在使用 MOXY 时从 @BeanParam 中丢失,但在 Jackson 中没有
【发布时间】:2023-03-13 17:15:01
【问题描述】:

我正在为我的公司开发一组 REST Web 服务。我们正在努力确定我们想要使用的技术。 当我使用 Jackson JSON 提供程序时,我有一个与 JAX-RS Jersey 2.6 一起使用的模板 Web 服务,但当我使用 Moxy 提供程序时,似乎没有正确编组 @QueryParam。

搜索可能包含多个“类型”,例如 type=keyword&type=product_number&type=fubar 这些映射到包含所有“类型”QueryParam 的列表类型。当我使用 Jackson 构建项目时,类型的值被正确收集到列表中,当我使用 MOXy 时,列表为空。 MOXy 确实映射了 BeanParam 中的所有其他查询和路径参数。

问题似乎在于 JERSEY 是怎样的 当我使用 Jackson 时,服务效果很好:

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>();
}

问题似乎在于类型参数的处理方式。使用 Jackson,QueryParams 类型被正确编组到列表中,但 MOXy 失败并且只返回一个空值。所以 getTypes 返回一个空列表。简单的 QueryParam 计数和语言处理正确。这是泽西岛的错误还是我需要对 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;
}

响应类:

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>

【问题讨论】:

    标签: moxy jersey-2.0


    【解决方案1】:

    默认情况下,EclipseLink JAXB (MOXy) 不会封送只有 getter 的属性。您可以添加 @XmlElement 注释以使其成为映射:

    @XmlElement
    public Map<String, Map<String,Object>>getAutoSuggestions() {
        return autoSuggestions;
    }
    

    默认情况下 MOXy 不使用映射键作为 JSON 键。下面是一个示例的链接,该示例说明了如何设置:

    【讨论】:

    • 很有趣,但不是真正的问题。问题是 QueryParam 类型的处理。它应该采用 type=keyword&type=product_number 的多个值并创建一个 List 类型。这不会发生。在 BeanParam 中正确处理了其他 QueryParam,但不是类型。杰克逊正确地做到了这一点。有注释吗?还是一个错误?
    • @user3366623 - MOXy 和 Jackson 不会自动处理 QueryParams。必须有在响应对象上设置它的逻辑。然后 MOXy 不会编组,因为您有一个 get only 属性,没有 @XmlElement 注释。
    • 我有两个几乎相同的 Eclipse 项目,它们的不同之处在于一个是基于 Jackson 的,另一个是 MOXy。 Jackson 版本正确地将 type= 的多个参数转换为字符串列表,而 MOXy 版本没有。 List QueryParam 为空。其他 QueryParams 得到正确处理。如果不是 MOXY 那是唯一的区别。
    • 将 @XmlElement 添加到 AutoSuggestParam 没有任何区别
    【解决方案2】:

    我发现了问题所在。它与 MOXy 无关,将 genson-0.98.jar 添加到路径中解决了 QueryParam 未在 BeanParam 中编组的问题。

    将@XmlElement 添加到资源确实使Moxy 工作,有点。如果我将 XmlElement 添加到响应类中的地图,我现在会收到一个错误: javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: org/eclipse/persistence/internal/libraries/asm/ClassWriter

    但这是一个新问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 2014-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多