我正在创建我的第一个Web服务,所以可能是我错过了一些非常简单的东西。 我在Eclipse Kepler中使用Jersey 2.x在Tomcat上创建了一个没有Maven的Web服务,它正在为没有参数的“@GET”请求工作(从浏览器和客户端应用程序测试),但我遇到了“@POST”的问题(代码如下)。这实际上是一个具有非常复杂的过滤条件的get请求。
@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:找不到媒体类型= application / json的MessageBodyReader”:
我怀疑问题是它无法将JSON转换为我的POJO对象,因此我在我的web.xml中放置了一个init参数,但它没有任何效果。另外,我尝试只发送一个FilterOption对象,认为ArrayList过于复杂,但它再次没有效果。
感谢您的时间:)
答案 0 :(得分:1)
我找到了避免预期解决方案的方法。我只是使用Strings并使用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);
}
.....
答案 1 :(得分:1)
通过实现2个接口MessageBodyWriter和MessageBodyReader,您仍然可以保留方法的签名,媒体类型,并仍然使用GSON来编组/解组。
我手边没有自己项目的代码示例,但以下内容看起来不错: http://eclipsesource.com/blogs/2012/11/02/integrating-gson-into-a-jax-rs-based-application/
答案 2 :(得分:1)
Jersey JSON支持是一组扩展模块,其中每个模块都包含需要注册到Feature
实例(客户端/服务器)的Configurable
实现。有多个框架为JSON处理和/或JSON到Java绑定提供支持。下面列出的模块通过将各个JSON框架集成到Jersey中来提供对JSON表示的支持。目前,Jersey集成了以下模块以提供JSON支持:
了解更多信息,请阅读泽西文档的chapter 9。
Moxy是json媒体支持的建议方法。 MOXy媒体模块是您不需要在客户端/服务器中明确注册它的功能(MoxyJsonFeature)的模块之一可配置,因为当您添加jersey-media-moxy时会自动发现并注册此功能模块到你的类路径。
要将MOXy用作JSON提供程序,您需要将jersey-media-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文件添加到项目中,以便通过jersey-media-moxy支持json媒体类型:
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}
答案 3 :(得分:1)
MessageBodyProviderNotFoundException
的典型原因是您尝试序列化为JSON的类未正确形成。
就我而言,我错过了一个无参数的构造函数。在我添加了一个空的无参数构造函数之后,一切正常。
答案 4 :(得分:0)
JAX-RS只能告诉它如何执行此操作,才能将JSON转换为FilterOption
实例。
一种常见的方法是使用JAXB:
@XmlRootElement
class FilterOption {
// members, getters, setters, constructors
}