2012-04-20 116 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

相關問題