2012-04-20 27 views
5

Tôi gặp sự cố khi đăng JSON lên dịch vụ REST REST - GET đang hoạt động hoàn hảo nhưng POST có vẻ phức tạp. Tôi đã làm việc về vấn đề này một thời gian, không có giải pháp cho đến nay. Bất kỳ sự giúp đỡ nào cũng được đánh giá cao! ?Sự cố với POST JSON tới dịch vụ REST của Jersey

Có vẻ như nó không thể tìm ra U RL để gửi json Đây là những gì Firebug console cho thấy:

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 

tôi đang làm POST như sau:

<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 lớp với @XmlRootElement:

@XmlRootElement 
public class StatusBean { 
    private String name; 

    public StatusBean() { 
    } 

    public String getName() { 
     return name; 
    } 

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

phương pháp Resource:

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

Các máy chủ, thiết lập với 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(); 
    } 
} 
+1

kiểm tra nhật ký máy chủ, là có bất cứ điều gì đó - tìm kiếm một ngoại lệ và dán chồng dấu vết. –

+0

Không có gì trong nhật ký máy chủ, đó là vấn đề – nihulus

+0

Bạn có thể đăng tệp web.xml của mình để có thể thấy cấu hình JAX-RS không? –

Trả lời

0

Bạn có chắc chắn rằng con đường bạn đang gửi bài đến là hoàn thành? Bạn nên xác định một Path chú thích vào phương pháp post và sử dụng trong URL bạn đang gửi bài đến:

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

Sau đó, sử dụng đường dẫn /data/postStatus để gửi yêu cầu của bạn:

<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

Anh ấy nhận được 400 Yêu cầu không tốt, không 404 Không tìm thấy, vì vậy có vẻ như đường dẫn là ok. –

2
  1. Hãy thử làm cho đậu của bạn serializable.

    @XmlRootElement 
    
    public class StatusBean implements Serializable { 
    .... 
    } 
    
  2. Kiểm tra url POST của bạn. Nó nên được `

    http://localhost:9998/ {projectname}/{} restservletmapping/dữ liệu

    Ví dụ, nếu web.xml của tôi trông như thế này và tên dự án của tôi là SampleProject

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

    URL sẽ là: http://localhost:9998/SampleProject/rest/data

    Bạn có thể sử dụng công cụ để thử nghiệm các dịch vụ REST như SOAP UI hoặc trình duyệt addons như Postman, REST CONSOLE vv

  3. Nếu những điều trên là tốt và dịch vụ REST sẽ trả lời bằng các công cụ kiểm tra. Sau đó, nó có thể là vấn đề của chính sách xuất xứ chéo trong ajax.

+0

Đối tượng của tôi được tuần tự động và không cần giao diện, nhưng nó thiếu setter và điều này nhắc tôi về thực tế đó. – Galya

1

Từ cấu hình máy chủ của bạn Tôi thấy rằng bạn chưa định cấu hình JAX-RS với Grizzly.Trên cơ sở của example mà bạn bằng cách nào đó phải vượt qua tài sản đó

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

Một tùy chọn cấu hình là sử dụng

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

và bắt đầu hoa râm server:

GrizzlyServerFactory.createHttpServer(BASE_URI, rc); 

Xem chi tiết: http://jersey.java.net/nonav/documentation/latest/user-guide.html (Chương "Triển khai tài nguyên gốc"). Hãy thử chạy ví dụ đầu tiên mà họ có.

+0

Ok, tôi đã kiểm tra ví dụ và thêm các ví dụ sau: Bản đồ initParams = new HashMap (); initParams.put ("com.sun.jersey.config.property.packages", "server"); Bộ chọnChọn bộ chọn đọc = GrizzlyWebContainerFactory.create ("http: // localhost: 9998 /", initParams); Nhưng vẫn nhận được 400 yêu cầu không hợp lệ ... – nihulus

+0

Một ý tưởng khác, xem câu trả lời được cập nhật ở trên –

2

Tôi gặp vấn đề tương tự. Vấn đề là dữ liệu của bạn không được tự động chuyển thành chuỗi JSON. Vì vậy, bạn chỉ cần gọi JSON.stringify (...) trên dữ liệu của mình trước khi đăng:

<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> 

Điều này sẽ hiệu quả.

0

Có thể bạn đã quên đăng ký trình ánh xạ JSON, tức là Jackson (hoặc bất kỳ người lập bản đồ nào bạn sử dụng). Tính năng không được kích hoạt tự động, bạn phải tải các lớp trong ResourceConfig của bạn:

org.glassfish.jersey.jackson.JacksonFeature.class 

sample

also, see JSON howto

Các vấn đề liên quan