我一直在谷歌搜索我的屁股试图找出如何做到这一点:我有一个泽西岛REST服务。调用REST服务的请求包含一个JSON对象。我的问题是,从Jersey POST方法实现中,我如何访问HTTP请求正文中的JSON?在Jersey服务中使用JSON对象
任何提示,技巧,示例代码指针将不胜感激。
谢谢...
--Steve
我一直在谷歌搜索我的屁股试图找出如何做到这一点:我有一个泽西岛REST服务。调用REST服务的请求包含一个JSON对象。我的问题是,从Jersey POST方法实现中,我如何访问HTTP请求正文中的JSON?在Jersey服务中使用JSON对象
任何提示,技巧,示例代码指针将不胜感激。
谢谢...
--Steve
我不知道你将如何获得在JSON字符串本身,但是你可以在它包含如下的数据肯定会获得:
定义一个JAXB注释的Java类(C),它具有与在请求上传递的JSON对象相同的结构。
例如一个JSON消息:
使用类似:
@XmlAccessorType(XmlAccessType.FIELD)
public class C
{
public String A;
public String B;
}
然后,你可以在你的资源类定义与C型的参数的方法,当新泽西调用你的方法,JAXB的对象将根据POST的JSON对象创建。
@Path("/resource")
public class MyResource
{
@POST
public put(C c)
{
doSomething(c.A);
doSomethingElse(c.B);
}
}
不幸的是,JSON字符串基本上被用作字典而不是真正的POJO。我宁愿不必为JSON对象创建一个新的POJO。 – Steve 2009-11-02 17:51:44
有你看着用化MessageBodyReader(http://jackson.codehaus.org/javadoc/jax-rs/1.0/javax/ws/rs/ext/MessageBodyReader.html)。没有尝试过自己,但你也许可以在这一水平获得和JSON流转换为地图等 – Andy 2009-11-02 17:57:07
其实事实证明,它的很多比我想象的简单。我可以将HTTP请求的主体作为字符串参数获取,然后使用任何JSON库(当前使用Google GSON)将请求数据转换为本地对象。 – Steve 2009-11-25 21:11:17
使用JSON作为值提交/ POST表单/ HTTP.POST。
@QueryParam jsonString
公共desolveJson(jsonString)
我想过这样做。这只是我不想要的方式。有几个工具包将完整的JSON放入HTTP请求的实际主体中,如果可能的话,我想遵循该模式。 – Steve 2009-11-02 21:12:54
这使您可以访问原始帖子。
@POST
@Path("/")
@Consumes("text/plain")
@Produces(MediaType.APPLICATION_JSON)
public String processRequset(String pData) {
// do some stuff,
return someJson;
}
这是一种从我的客户端传递JSON的流畅而简单的方法,并且不需要服务器/客户端知道我传递的对象。我只是使用GSON将其序列化并附加到帖子中。工作很棒!谢谢。 – bh5k 2012-10-11 17:17:53
正如已经建议,改变@Consumes
的Content-Type到text/plain
将工作,但它似乎从一个角度REST API点不正确。
想象一下,您的客户必须将JSON发布到您的API,但需要将Content-Type标头指定为text/plain
。我认为这并不干净。简而言之,如果您的API接受JSON,那么请求标头应指定Content-Type: application/json
。
为了接受JSON,但将其序列化为String
对象而不是POJO,您可以实施自定义MessageBodyReader。这样做非常简单,您不必在API规范中妥协。
这是值得阅读文档MessageBodyReader所以你知道它是如何工作的。这是我如何做到了:
步骤1.实现自定义MessageBodyReader
@Provider
@Consumes("application/json")
public class CustomJsonReader<T> implements MessageBodyReader<T> {
@Override
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations,MediaType mediaType) {
return true;
}
@Override
public T readFrom(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
InputStream entityStream) throws IOException, WebApplicationException {
/* Copy the input stream to String. Do this however you like.
* Here I use Commons IOUtils.
*/
StringWriter writer = new StringWriter();
IOUtils.copy(entityStream, writer, "UTF-8");
String json = writer.toString();
/* if the input stream is expected to be deserialized into a String,
* then just cast it
*/
if (String.class == genericType)
return type.cast(json);
/* Otherwise, deserialize the JSON into a POJO type.
* You can use whatever JSON library you want, here's
* a simply example using GSON.
*/
return new Gson().fromJson(json, genericType);
}
}
以上的基本概念是,以检查是否输入流有望被转换为String
(由Type genericType
指定)。如果是,那么可简单地把JSON到指定type
(这将是一个String
)。如果预期的类型是某种POJO,则使用JSON库(例如Jackson或GSON)将其反序列化为POJO。
步骤2.绑定您的MessageBodyReader
这取决于你所使用的架构。我发现吉斯和泽西一起工作得很好。以下是我在吉斯绑定我MessageBodyReader:
在我JerseyServletModule我绑定读者像这样 -
bind(CustomJsonReader.class).in(Scopes.SINGLETON);
以上CustomJsonReader
将反序列化JSON的有效载荷送入的POJO还有,如果你只是想生JSON,String
对象。
做这种方式的好处是,它会接受Content-Type: application/json
。换句话说,你的请求处理程序可以被设置为使用JSON,这似乎是正确的:
@POST
@Path("/stuff")
@Consumes("application/json")
public void doStuff(String json) {
/* do stuff with the json string */
return;
}
新泽西支持使用抛弃型的JSONObject和JSONArray所解析的JSONObject低级别的访问。
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.8</version>
</dependency>
例如:
{
"A": "a value",
"B": "another value"
}
@POST
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
public void doStuff(JSONObject json) {
/* extract data values using DOM-like API */
String a = json.optString("A");
Strong b = json.optString("B");
return;
}
更多的例子参见Jersey documentation。
这不适合我。我得到... '无法识别的字段“A”(类org.json.JSONObject),未标记为可忽略的# ...并且如果我添加以下内容... 'mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false );' ......那么对象来通过空'{}' – crowmagnumb 2014-10-23 22:14:26
,这是不行的。我得到415错误。有没有解决方案,以及为低级别json访问添加什么依赖关系? – Jugi 2017-05-20 12:44:06
现在所面临的问题similiar。有没有解决方案可以使用对JSONObject的低级访问? – Jugi 2017-05-20 11:45:29