2012-04-20 146 views
5

我有一个将JSON发布到Jersey REST服务的问题 - GET工作正常,但POST看起来很棘手。我一直在研究这个问题一段时间,目前还没有解决方案。任何帮助深表感谢! ?发布POST JSON到Jersey REST服务

看来它不能找到在U RL发送JSON这里是萤火控制台显示:

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 

我做的是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类与@XmlRootElement:

@XmlRootElement 
public class StatusBean { 
    private String name; 

    public StatusBean() { 
    } 

    public String getName() { 
     return name; 
    } 

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

资源方法:

@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; 
    } 
} 

的服务器,建立与灰熊:

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

检查服务器日志,还有什么存在 - 找一个异常和粘贴堆栈跟踪。 – 2012-04-20 11:28:52

+0

没有在服务器日志中,这就是问题 – nihulus 2012-04-20 11:31:03

+0

你可以发布你的web.xml,所以我们可以看到JAX-RS配置? – 2012-04-20 11:33:03

回答

0

你确定要发布的路径是否完整?你应该定义在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; 
    } 
} 

然后使用/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> 
+0

他的得到400坏请求,而不是404找不到,所以看起来路径没问题。 – 2012-04-20 11:28:05

2
  1. 尝试让你的bean可序列化。

    @XmlRootElement 
    
    public class StatusBean implements Serializable { 
    .... 
    } 
    
  2. 检查您的POST网址。它应该是`

    http://localhost:9998/ {项目名称}/{} restservletmapping /数据

    例如,如果我的web.xml看起来是这样的,我的项目名称是SampleProject

    <servlet-mapping> 
    <servlet-name>Jersey REST Service</servlet-name> 
    <url-pattern>/rest/*</url-pattern> 
    </servlet-mapping> 
    

    网址是: http://localhost:9998/SampleProject/rest/data

    可以使用工具来测试REST服务,如SOAP UI或浏览器插件像邮递员,REST控制台等

  3. 如果上述事情都很好,REST服务正在为测试工具提供响应。 然后它可能是ajax中的跨域策略问题。

+0

我的对象是动态序列化的,不需要接口,但它缺少setter,这让我想起了这个事实。 – Galya 2016-03-15 09:48:58

1

从您的服务器配置我看到你还没有配置与灰熊的JAX-RS。在那个example的基础,你应该以某种方式传递这样的属性

Map<String,String> initParams = new HashMap<String, String>(); 
initParams.put("com.sun.jersey.config.property.packages", "package.with.your.StatusBean.class"); 

另一个配置选择是使用

ResourceConfig rc = new PackagesResourceConfig("your.package.with.resources"); 

,并开始灰熊服务器:

GrizzlyServerFactory.createHttpServer(BASE_URI, rc); 

查看详情:http://jersey.java.net/nonav/documentation/latest/user-guide.html(章“部署根资源”)。试着运行他们的第一个例子。

+0

好吧,我检查了这个例子,并添加了这些: Map initParams = new HashMap (); initParams.put(“com.sun.jersey.config.property.packages”,“server”); SelectorThread selector = GrizzlyWebContainerFactory.create(“http:// localhost:9998 /”,initParams); 但仍然收到400个不好的请求... – nihulus 2012-04-20 13:15:53

+0

还有一个想法,请参阅上面的更新回答 – 2012-04-20 13:55:38

2

我有同样的问题。问题是您的数据不会自动转换为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> 

这应该工作。

0

您可能已经忘记注册JSON映射器,即Jackson(或任何您使用的映射器)。该功能不会自动启用,你必须加载在你ResourceConfig类:

org.glassfish.jersey.jackson.JacksonFeature.class 

sample

also, see JSON howto