2017-04-05 86 views
-3

因爲我得到了一些不好的評論,我重寫了這個問題...REST HTTP POST JSON對象400錯誤的Android

我有一個HTTP REST服務器和客戶端(Android應用程序)。我編寫了幾個可以正常工作的API,但是有一個API會給我一個400錯誤,如果我在服務器中放置一個斷點,它甚至不會觸發它。所以,我想明白爲什麼它失敗:(...

這是非常簡單的,我有一個值對象稱爲具有幾個屬性的報警,我想發佈到服務器註冊的對象在。數據庫

這是輸出:

Callback failure for call to http://10.0.0.3:8080/... 
java.io.IOException: Unexpected code Response{protocol=http/1.1, code=400, message=, url=http://10.0.0.3:8080/BiTrack_API/api/assets/registerAlarm} 
    at it.bitrack.fabio.bitrack.AlarmView$2$1.onResponse(AlarmView.java:438) 
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135) 
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 

這是我的客戶端Android的按鈕偵聽:

View.OnClickListener addAlarmAction = new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      try { 

       alarm.setThreshold(Float.parseFloat(thresholdEditText.getText().toString())); 
       String alarmJson = j.makeJsonBodyForAlarmRegistration(alarm); 
       tagLinearLayout.setVisibility(view.GONE); 
       operatorLinearLayout.setVisibility(view.GONE); 
       thresholdLinearLayout.setVisibility(view.GONE); 
       assetSpinner.setSelection(0); 

       r.attemptAddNewAlarm(alarmJson, 

         new Callback() { 
          @Override public void onFailure(Call call, IOException e) { 
           e.printStackTrace(); 
          } 

          @Override public void onResponse(Call call, Response response) throws IOException { 
           try (final ResponseBody responseBody = response.body()) { 
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 

            Headers responseHeaders = response.headers(); 
            for (int i = 0, size = responseHeaders.size(); i < size; i++) { 
             System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i)); 
            } 

            final String responseBodyString = responseBody.string(); 
            final int resultCode = response.code(); 

            try { 

             getActivity().runOnUiThread(new Runnable() { 
              @Override 
              public void run() { 

               Log.i("BiTrack", "attemptAddNewAlarm RESULT: " + resultCode); 
               executeAlarmRegistration(resultCode); 

              } 
             }); 

            } catch (Exception e) { 

             e.printStackTrace(); 

            } 
           } 
          } 
         }); 

      } catch (Exception e) { 

       e.printStackTrace(); 

      } 

     } 
    }; 

這是我生成的Json體F中的代碼或在客戶端的POST:

public String makeJsonBodyForAlarmRegistration (Alarm alarm) { 

     Gson gson = new Gson(); 

     String jsonAlarm = gson.toJson(alarm); 

     return jsonAlarm; 

    } 

這是在客戶端的實際POST代碼(安卓)側:

public void attemptAddNewAlarm(String json, Callback callback) throws Exception { 

     final OkHttpClient client = new OkHttpClient(); 

     RequestBody body = RequestBody.create(JSON, json); 
     Request request = new Request.Builder() 
       .url(WEB_SERVER + "BiTrack_API/api/assets/registerAlarm") 
       .post(body) 
       .build(); 

     client.newCall(request).enqueue(callback); 
    } 

這是我的服務器端代碼:

@POST 
    @Path("/registerAlarm") 
    @Produces(MediaType.APPLICATION_JSON) 
    @Consumes(MediaType.APPLICATION_JSON) 
    public Response registerAlarm(Alarm alarm) { 

     System.out.println("Received API Call: registerAlarm for alarm tagId: " + alarm.getTagId() + " operatorId: " + alarm.getOperatorId() + " treshold: " + alarm.getThreshold()); 

     DataProcessor dp = new DataProcessor(); 
     AssetUpdateDAO aDAO = new AssetUpdateDAO(); 

     ArrayList<Alarm> customerAlarms = aDAO.getUserAlarmsForAsset(alarm.getUserId(), alarm.getAssetId()); 


     if (dp.isNewAlarmDuplicate(customerAlarms, alarm)) { 

      return Response.status(480).build(); // duplicated error 

     } else { 

      int response = aDAO.insertAssetUserAlarm(alarm.getUserId(), alarm.getAssetId(), alarm.getTagId(), alarm.getOperatorId(), alarm.getThreshold()); 

      if (response == -5) { 
       return Response.status(484).build(); // something went wrong while inserting alarm into db 
      } else { 
       return Response.status(200).build(); 
      } 

     } 

    } 

這是我的報警值對象(客戶端和服務器中的同一類):

public class Alarm { 

    public Alarm() { 

    } 

    protected int id; 
    protected int userId; 
    protected int assetId; 
    protected int tagId; 
    protected int operatorId; 
    protected float threshold; 
    protected String networkAssetCode; 

    public String getNetworkAssetCode() { 
     return networkAssetCode; 
    } 
    public void setNetworkAssetCode(String networkAssetCode) { 
     this.networkAssetCode = networkAssetCode; 
    } 
    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 
    public int getUserId() { 
     return userId; 
    } 
    public void setUserId(int userId) { 
     this.userId = userId; 
    } 
    public int getAssetId() { 
     return assetId; 
    } 
    public void setAssetId(int assetId) { 
     this.assetId = assetId; 
    } 
    public int getTagId() { 
     return tagId; 
    } 
    public void setTagId(int tagId) { 
     this.tagId = tagId; 
    } 
    public int getOperatorId() { 
     return operatorId; 
    } 
    public void setOperatorId(int operatorId) { 
     this.operatorId = operatorId; 
    } 
    public float getThreshold() { 
     return threshold; 
    } 
    public void setThreshold(float threshold) { 
     this.threshold = threshold; 
    } 

} 

我真的很感謝任何幫助......

+0

向我們顯示您的代碼。您正在調用的端點和實體此JSON應該映射到。 – Januson

+0

你認爲我們應該幫助你什麼?向我們展示代碼。我們不需要理論課。 –

+0

@ user1060551請顯示您的代碼,以便我們能夠幫助您。 – user3441151

回答

0

我發現了這個問題!經過48小時尋找不可能,發現我已經在服務器端的對象屬性做了一個小的更新,沒有在客戶端複製...

0

爲了幫助你,端點代碼是必需的。現在甚至不清楚你的API使用了什麼技術棧。

但是,從存在的信息...端點認爲您的JSON無效。

400錯誤的請求

請求不能被服務器由於格式不正確的語法 理解。如果沒有 修改,客戶端不應該重複請求。

在jax-rs中,有效負載在到達綁定到url en http方法的方法之前首先被反序列化。

反序列化可能失敗,它永遠達不到您設置的斷點。

什麼是有趣的是以下幾點:

  • 日誌或異常從服務器。客戶端異常沒有什麼幫助,因爲服務器返回這個響應。
  • 通過線路發送的實際(json)有效負載。
  • 在服務器端使用什麼反序列化機制?反思還是你做了你自己的解串器?
+0

我已經發布的代碼,你可以請檢討它?謝謝! – user1060551

+0

我要求一些額外的信息。我看起來像你在服務器端使用jax-rs。你可能知道哪個實現?澤西島,CXF,resteasy,...?哪個json de-/serailizer在服務器端配置?傑克遜,格森,...? – ipper

+0

在服務器上,使用Jersey + Jackson – user1060551