I have a problem with posting JSON to a Jersey REST service - GET is working perfectly but POST seems tricky. I've been working on this problem for awhile now, with no solution so far. Any help is much appreciated!
将JSON发布到Jersey REST服务时遇到问题 - GET工作正常但POST似乎很棘手。我一直在研究这个问题,到目前为止还没有解决方案。任何帮助深表感谢!
It seems it cant find the U RL to send the json?Here is what FireBug console shows:
它似乎无法找到U RL发送json?这是FireBug控制台显示的内容:
POST http://localhost:9998/data 400 Bad Request
Post source: name=Tony
**Response Headers**
Connection close
Content-Length 0
Content-Type text/html; charset=iso-8859-1
Date Fri, 20 Apr 2012 10:13:24 GMT
**Request Headers**
Accept application/json, text/javascript, */*; q=0.01
Accept-Encoding gzip, deflate
Accept-Language sv-se,sv;q=0.8,en-us;q=0.5,en;q=0.3
Connection keep-alive
Content-Length 9
Content-Type application/json; charset=UTF-8
Host localhost:9998
Referer http://localhost:9998/static/page.html
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0
X-Requested-With XMLHttpRequest
I'm doing the POST as follows:
我按照以下方式进行POST:
<button id='btn' value="knapp" name="knapp" />
<script type="text/javascript">
$('#btn').click(function(){
$.ajax({
url: '/data',
type: 'POST',
contentType: 'application/json',
data: {name:"Tony"},
dataType: 'json'
});
})
</script>
Javabean class with @XmlRootElement:
带有@XmlRootElement的Javabean类:
@XmlRootElement
public class StatusBean {
private String name;
public StatusBean() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Resource method:
资源方法:
@Path("/data")
public class PostData {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public StatusBean post(StatusBean sb) {
System.out.println(sb);
return sb;
}
}
The server, set up with Grizzly:
服务器,与Grizzly一起设置:
public class Main {
public static final URI BASE_URI = getBaseURI();
public static void main(String[] args) throws IOException {
HttpServer httpServer = startServer();
Map<String,String> initParams = new HashMap<String, String>();
initParams.put("com.sun.jersey.config.property.packages", "server");
SelectorThread selector = GrizzlyWebContainerFactory.create("http://localhost:9998/", initParams );
System.out.println(String.format("Jersey app started with WADL available at "
+ "%sapplication.wadl\nTry out %shelloworld\nHit enter to stop it...",
BASE_URI, BASE_URI));
System.in.read();
httpServer.stop();
}
protected static HttpServer startServer() throws IOException {
System.out.println("Starting grizzly...");
ClassNamesResourceConfig rc = new ClassNamesResourceConfig(PostData.class);
// rc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true);
HttpServer server = GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
server.getServerConfiguration().addHttpHandler(new StaticHttpHandler(new File(".").getAbsolutePath()), "/static");
return server;
}
private static int getPort(int defaultPort) {
String port = System.getProperty("jersey.test.port");
if (null != port) {
try {
return Integer.parseInt(port);
} catch (NumberFormatException e) {
}
}
return defaultPort;
}
private static URI getBaseURI() {
return UriBuilder.fromUri("http://localhost/").port(getPort(9998)).build();
}
}
5 个解决方案
#1
2
-
Try making your bean serializable.
尝试使您的bean可序列化。
@XmlRootElement public class StatusBean implements Serializable { .... }
-
Check your POST url. It should be `
检查你的POST网址。它应该是`
http://localhost:9998/{projectname}/{restservletmapping}/data
HTTP://本地主机:9998 / {项目名称} / {restservletmapping} /数据
For example, if my web.xml looks like this and my project name is SampleProject
例如,如果我的web.xml看起来像这样,我的项目名称是SampleProject
<servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>
URL would be : http://localhost:9998/SampleProject/rest/data
URL将是:http:// localhost:9998 / SampleProject / rest / data
You can use tools for testing REST services like SOAP UI or browser addons like POSTMAN, REST CONSOLE, etc.
您可以使用工具来测试REST服务,如SOAP UI或浏览器插件,如POSTMAN,REST CONSOLE等。
-
If above things are fine and REST service is giving response with testing tools. Then it could be problem of Cross Origin Policy in ajax.
如果上面的事情很好,REST服务就会通过测试工具给出响应。那么它可能是ajax中的跨源策略问题。
#2
2
I had the same problem. The issue is that your data is not converted to JSON string automatically. So you just need to call JSON.stringify(...) on your data before posting it:
我有同样的问题。问题是您的数据未自动转换为JSON字符串。所以你只需要在发布数据之前调用JSON.stringify(...):
<button id='btn' value="knapp" name="knapp" />
<script type="text/javascript">
$('#btn').click(function(){
$.ajax({
url: '/data',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({name:"Tony"}),
dataType: 'json'
});
})
</script>
This should work.
这应该工作。
#3
1
From your server config I see that you haven't configured JAX-RS with Grizzly. On the base of that example you should somehow pass such property
从您的服务器配置中我发现您还没有使用Grizzly配置JAX-RS。在该示例的基础上,您应该以某种方式传递此类属性
Map<String,String> initParams = new HashMap<String, String>();
initParams.put( "com.sun.jersey.config.property.packages", "package.with.your.StatusBean.class" );
Another configuration option is to use
另一种配置选项是使用
ResourceConfig rc = new PackagesResourceConfig("your.package.with.resources");
and start grizzly server:
并启动grizzly服务器:
GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
See details: http://jersey.java.net/nonav/documentation/latest/user-guide.html (Chapter "Deploying the root resource"). Try to run first example they have.
请参阅详细信息:http://jersey.java.net/nonav/documentation/latest/user-guide.html(“部署根资源”一章)。尝试运行他们拥有的第一个示例。
#4
0
Are you sure that the path you're posting to is complete? You should define another Path
annotation on the post
method and use that in the URL you're posting to:
您确定要发布的路径是否完整?您应该在post方法上定义另一个Path注释,并在您要发布到的URL中使用它:
@Path("/data")
public class PostData {
@Path("/postStatus")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public StatusBean post(StatusBean sb) {
System.out.println(sb);
return sb;
}
}
Then use the /data/postStatus
path to post your request to:
然后使用/ data / postStatus路径将您的请求发布到:
<button id='btn' value="knapp" name="knapp" />
<script type="text/javascript">
$('#btn').click(function(){
$.ajax({
url: '/data/postStatus',
type: 'POST',
contentType: 'application/json',
data: {name:"Tony"},
dataType: 'json'
});
})
</script>
#5
0
You have probably forgotten to register the JSON mapper, i.e. Jackson (or whatever mapper you use). The feature is not enabled automatically, you have to load the class in your ResourceConfig:
您可能忘记注册JSON映射器,即Jackson(或您使用的任何映射器)。该功能未自动启用,您必须在ResourceConfig中加载该类:
org.glassfish.jersey.jackson.JacksonFeature.class
样品
另外,请参阅JSON howto
#1
2
-
Try making your bean serializable.
尝试使您的bean可序列化。
@XmlRootElement public class StatusBean implements Serializable { .... }
-
Check your POST url. It should be `
检查你的POST网址。它应该是`
http://localhost:9998/{projectname}/{restservletmapping}/data
HTTP://本地主机:9998 / {项目名称} / {restservletmapping} /数据
For example, if my web.xml looks like this and my project name is SampleProject
例如,如果我的web.xml看起来像这样,我的项目名称是SampleProject
<servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>
URL would be : http://localhost:9998/SampleProject/rest/data
URL将是:http:// localhost:9998 / SampleProject / rest / data
You can use tools for testing REST services like SOAP UI or browser addons like POSTMAN, REST CONSOLE, etc.
您可以使用工具来测试REST服务,如SOAP UI或浏览器插件,如POSTMAN,REST CONSOLE等。
-
If above things are fine and REST service is giving response with testing tools. Then it could be problem of Cross Origin Policy in ajax.
如果上面的事情很好,REST服务就会通过测试工具给出响应。那么它可能是ajax中的跨源策略问题。
#2
2
I had the same problem. The issue is that your data is not converted to JSON string automatically. So you just need to call JSON.stringify(...) on your data before posting it:
我有同样的问题。问题是您的数据未自动转换为JSON字符串。所以你只需要在发布数据之前调用JSON.stringify(...):
<button id='btn' value="knapp" name="knapp" />
<script type="text/javascript">
$('#btn').click(function(){
$.ajax({
url: '/data',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({name:"Tony"}),
dataType: 'json'
});
})
</script>
This should work.
这应该工作。
#3
1
From your server config I see that you haven't configured JAX-RS with Grizzly. On the base of that example you should somehow pass such property
从您的服务器配置中我发现您还没有使用Grizzly配置JAX-RS。在该示例的基础上,您应该以某种方式传递此类属性
Map<String,String> initParams = new HashMap<String, String>();
initParams.put( "com.sun.jersey.config.property.packages", "package.with.your.StatusBean.class" );
Another configuration option is to use
另一种配置选项是使用
ResourceConfig rc = new PackagesResourceConfig("your.package.with.resources");
and start grizzly server:
并启动grizzly服务器:
GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
See details: http://jersey.java.net/nonav/documentation/latest/user-guide.html (Chapter "Deploying the root resource"). Try to run first example they have.
请参阅详细信息:http://jersey.java.net/nonav/documentation/latest/user-guide.html(“部署根资源”一章)。尝试运行他们拥有的第一个示例。
#4
0
Are you sure that the path you're posting to is complete? You should define another Path
annotation on the post
method and use that in the URL you're posting to:
您确定要发布的路径是否完整?您应该在post方法上定义另一个Path注释,并在您要发布到的URL中使用它:
@Path("/data")
public class PostData {
@Path("/postStatus")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public StatusBean post(StatusBean sb) {
System.out.println(sb);
return sb;
}
}
Then use the /data/postStatus
path to post your request to:
然后使用/ data / postStatus路径将您的请求发布到:
<button id='btn' value="knapp" name="knapp" />
<script type="text/javascript">
$('#btn').click(function(){
$.ajax({
url: '/data/postStatus',
type: 'POST',
contentType: 'application/json',
data: {name:"Tony"},
dataType: 'json'
});
})
</script>
#5
0
You have probably forgotten to register the JSON mapper, i.e. Jackson (or whatever mapper you use). The feature is not enabled automatically, you have to load the class in your ResourceConfig:
您可能忘记注册JSON映射器,即Jackson(或您使用的任何映射器)。该功能未自动启用,您必须在ResourceConfig中加载该类:
org.glassfish.jersey.jackson.JacksonFeature.class
样品
另外,请参阅JSON howto