2013-10-03 57 views
1

我正在创建我的第一个Web服务,所以可能是因为我缺少一些非常简单的东西。 我在Eclipse Kepler中使用Jersey 2.x在Tomcat上创建了一个没有Maven的Web服务,它正在为不带参数(从浏览器和客户端应用程序测试)的“@GET”请求工作,但我遇到了“@POST” (代码如下)。这实际上是一个具有非常复杂的过滤条件的获取请求。MessageBodyProviderNotFoundException执行带有JSON数组对象的Post对象

@POST 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public String getFilteredPictures(ArrayList<FilterOption> filters) 
{ 
    PictureProvider provider = new PictureProvider(); 
    ArrayList<PictureInfo> pictures; 
    try 
    { 
     pictures = provider.getPictures(filters); 
     Gson gson = new Gson(); 
     return gson.toJson(pictures); 
    } 
    catch (SQLException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     return null; 
    } 
} 

我创建了一个虚拟的客户端,只看到上面的方法工作:

HttpClient httpclient = new DefaultHttpClient(); 
    Gson gson = new Gson(); 
    HttpPost request = new HttpPost(SERVICE_URI + picturesServiceEndPoint); 
    //create dummy data 
    ArrayList<FilterOption> filters = new ArrayList<>(); 
    ArrayList<String> options = new ArrayList<>(); 
    options.add("Black"); 
    filters.add(new FilterOption("Color", options)); 
    StringEntity postParam = StringEntity(gson.toJson(filters), "UTF-8"); 
    postParam.setContentType("application/json"); 

    request.setEntity(postParam); 
    request.setHeader("Accept", "application/json"); 
    try 
    { 
     HttpResponse response = httpclient.execute(request); 
     HttpEntity entity = response.getEntity(); 
     if (entity != null) 
     { 
      //obtain results.. 

     } 
    } 
    catch (ClientProtocolException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 

当我运行客户端对服务器抛出以下异常” .MessageBodyProviderNotFoundException:化MessageBodyReader找不到媒体类型=应用程序/ JSON“: enter image description here

我怀疑的问题是,它不能转换JSON到我的POJO对象,所以我把一个初始参数在web.xml中我的,但它没有任何效果。另外,我试着发送一个FilterOption对象,认为ArrayList太复杂了,但它又没有效果。

感谢您的时间:)

+0

请包含'FilterOption'的代码。它有JAXB注释吗? – 2013-10-03 15:45:20

+0

不,它没有注释。 – Laviniux

+0

阅读泽西文档第9章:[支持常见媒体类型表示] [1] –

回答

1

我找到了一种方法,以避免预期的解决方案。我只是对字符串进行操作,并与GSON库解析它们:

@POST 
// @Consumes(MediaType.APPLICATION_JSON) 
// @Produces(MediaType.APPLICATION_JSON) 
public String getFilteredPictures(String jsonFilters) 
{ 
    PictureProvider provider = new PictureProvider(); 
    ArrayList<PictureInfo> pictures = null; 
    ArrayList<FilterOption> filters = null; 
    if (jsonFilters != null) 
    { 
     Type collectionType = new TypeToken<ArrayList<FilterOption>>() 
     {}.getType(); 
     filters = gson.fromJson(jsonFilters, collectionType); 
    } 
    ..... 
0

JAX-RS只能转换JSON和从FilterOption例如,如果你告诉它如何做到这一点。

的常用方法是使用JAXB此:

@XmlRootElement 
class FilterOption { 
    // members, getters, setters, constructors 
} 
+0

我添加注释,但我得到相同的异常:-( – Laviniux

+0

谢谢您的回答,我确定我错过了某些东西启用JSON解析直到我发现问题,我手动执行解析。 – Laviniux

1

新泽西JSON支持之际,一组扩展模块,其中每个模块包含的实现需要注册到Configurable实例(客户端/服务器)的Feature。有多个框架为JSON处理和/或JSON到Java的绑定提供支持。通过将各个JSON框架集成到Jersey中,下面列出的模块提供了对JSON表示形式的支持。目前,泽西具有以下模块集成,提供JSON支持:

  • MOXY - 经由MOXY JSON绑定支持是默认和支撑JSON自新泽西2.0在新泽西的应用程序结合优选方式。当JSON MOXy模块位于类路径上时,Jersey将自动发现模块并通过MOXy在应用程序中无缝启用JSON绑定支持。 (请参见第4.3节“自动发现的功能”。)
  • 为JSON处理(JSON-P)
  • 杰克逊
  • 抛弃

有关详细信息的Java API读取球衣文档chapter 9

Moxy:

Moxy是Json媒体支持的建议方法。 MOXy媒体模块是您不需要在您的客户端/服务器中明确注册其功能(MoxyJsonFeature)的模块之一可配置,因为当您将jersey-media-moxy模块添加到您的课堂时,此功能会自动发现并注册。路径。

要使用莫西为您的JSON提供你需要的球衣,媒体MOXY模块添加到您的pom.xml文件:

<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-moxy</artifactId> 
    <version>2.15</version> 
</dependency> 

如果你不使用Maven确保有需要的所有依存关系。见jersey-media-moxy dependencies
你需要这些jar文件,以便通过球衣,媒体MOXY支持JSON媒体类型添加到您的项目:

  • 新泽西媒体MOXY-2.15.jar
  • org.eclipse.persistence。核心2.5.0-rc2.jar
  • org.eclipse.persistence.antlr-2.5.0.jar
  • org.eclipse.persistence.moxy-2.5.0.jar
  • 球衣,实体filtering- 2.3.1.jar

用法:

一些普通类:

public class MyJAXBBean{ 

    private String name = "jack"; 
    private int id = 12; 

    public MyJAXBBean() { 

    } 

    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public int getId() { 
     return this.id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 
} 

以及运行球衣客户端的例子一个主类:

public static void main(String[] args) { 
    //ClientConfig cc = new ClientConfig().register(new JacksonFeature()); 
    Client client = ClientBuilder.newClient(); 
    WebTarget target = client.target("http://localhost:8084/myhost/test"); 

    Form form = new Form(); 
    form.param("x", "foo"); 
    form.param("y", "bar"); 

    MyJAXBBean bean; 
    bean = target.request(MediaType.APPLICATION_JSON_TYPE) 
      .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), 
        MyJAXBBean.class); 
    System.out.println(bean); 
} 

服务器(http://localhost:8084/myhost/test)的JSON响应必须在以下格式:

{"name":"haleh", "id":3} 
1

t的典型原因他MessageBodyProviderNotFoundException是你尝试序列化为JSON的类没有正确形成。

在我的情况下,我错过了一个无参数的构造函数。在我添加了一个空的无参构造函数之后,所有的工作都完成了。