使用spring和resttemplate postForObject获取http 400 Bad Request Error

时间:2014-05-14 08:30:21

标签: android spring rest webservice-client resttemplate

在执行对我的Webservice的POST调用时,我一直收到Bad Request HttpClient 400 Exception。 我无法弄清楚错误是从客户端还是服务器端发起的......请帮我跟踪这个错误。但是因为使用curl的pst调用工作正常,我认为错误源于客户端,并且构造了springtemplate

GET通话工作正常! curl的帖子调用工作正常

C:\Users\pk>curl -v  -H "Accept: application/json" -H "Content-Type: application
/json" -X POST http://127.0.0.1:8080/TblGps/update -d @json.txt

如果有人可以指出我错在哪里,那就是适当的。

我的客户代码是:

什么时候来到resttemplate.postForObject ....一个Http 400错误的请求异常被抛出 - GET工作正常,curl命令行调用post也在工作

    private class HttpRequestTask extends AsyncTask<Void, Void, TblGps> {
        @Override
        protected TblGps doInBackground(Void... params) {
            try {
                final String urlGET = "http://10.0.2.2:8080/TblGps/get?id=1";
                final String urlPOST = "http://10.0.2.2:8080/TblGps/update/";


                RestTemplate restTemplate = new RestTemplate();
                restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

                //get Object from Service
                TblGps gps = (TblGps) restTemplate.getForObject(urlGET,TblGps.class);


                // alter the Object Data
               gps.setDescr("success");

              //POST Object to Service Endpoint
              TblGps gpsResult = restTemplate.postForObject(urlPOST, "POST", TblGps.class, gps);


             return gpsResult;


            } catch (Exception e) {
                Log.e("REST call", e.getMessage(), e);
            }

            return null;
        }
}
}

我也尝试过restTemplate.postForEntity

 HttpHeaders headers = new HttpHeaders();

            headers.add("Accept", "application/json");
            headers.add("Content-Type", "application/json");
    HttpEntity ent = new HttpEntity(gps,headers);
          ResponseEntity<TblGps> out  = restTemplate.postForEntity(urlPOST, HttpMethod.POST, TblGps.class,ent);

我的控制器代码:

  @RequestMapping(value="/TblGps/update", method=RequestMethod.POST, consumes = "application/json",produces="application/json")
  @ResponseBody public TblGps post(@RequestBody  TblGps gps){

        logger.debug("/TblGps/update: " + gps.getId());
          System.out.println("save.............."+ gps);
          return Application.DataRepository.save(gps);
    }

我的控制台日志:端点的映射在控制台日志中也很正常

2014-05-14 08:15:37.850  INFO 2280 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-05-14 08:15:41.457  INFO 2280 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/TblGps/List],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.util.List<com.pekam.TblGps> com.pekam.TblGpsController.findAll()
2014-05-14 08:15:41.464  INFO 2280 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/TblGps/get],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public com.pekam.TblGps com.pekam.TblGpsController.findById(long)
2014-05-14 08:15:41.471  INFO 2280 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/TblGps/update],methods=[POST],params=[],headers=[],consumes=[application/json],produces=[application/xml || application/json],custom=[]}" onto public com.pekam.TblGps com.pekam.TblGpsController.post(com.pekam.TblGps)
2014-05-14 08:15:41.478  INFO 2280 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/*],methods=[GET || POST || DELETE || PUT || HEAD],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.pekam.TblGpsController.allFallback()
2014-05-14 08:15:42.701  INFO 2280 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-05-14 08:15:42.706  INFO 2280 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-05-14 08:15:56.645  INFO 2280 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2014-05-14 08:15:57.551  INFO 2280 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-05-14 08:15:57.665  INFO 2280 --- [           main] com.pekam.Application                    : Started Application in 46.091 seconds (JVM running for 46.681)

异常的堆栈跟踪:

400 Bad Request
: org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:76)
    at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:524)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:481)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:317)
    at com.pekam.myandroid.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:106)
    at com.pekam.myandroid.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:288)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:841)

这是我的数据类代码:

/**
 * The persistent class for the tblGps database table.
 * 
 */
@Entity
@Table(name="tblGps")
@NamedQuery(name="TblGps.findAll", query="SELECT t FROM TblGps t")
public class TblGps implements Serializable {
    private static final long serialVersionUID = 1L;
    private long id;
    private Timestamp date ;
    private String descr;
    private int gpsCordsX;
    private int gpsCordsY;
    private int userid;

    @SuppressWarnings("deprecation")
    public TblGps() {


        date= new Timestamp(0,0,0,0,0, 0, 0);
    }


    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    public long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }


    @Column(nullable=false)
    public Timestamp getDate() {
        return this.date;
    }

    public void setDate(Timestamp date) {
        this.date = date;
    }


    public String getDescr() {
        return this.descr;
    }

    public void setDescr(String descr) {
        this.descr = descr;
    }


    @Column(nullable=false, precision=53)
    public int getGpsCordsX() {
        return this.gpsCordsX;
    }

    public void setGpsCordsX(int gpsCordsX) {
        this.gpsCordsX = gpsCordsX;
    }


    @Column(nullable=false, precision=53)
    public int getGpsCordsY() {
        return this.gpsCordsY;
    }

    public void setGpsCordsY(int gpsCordsY) {
        this.gpsCordsY = gpsCordsY;
    }


    @Column(nullable=false)
    public int getUserid() {
        return this.userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

}

3 个答案:

答案 0 :(得分:2)

似乎客户端没有正确设置Accept标头。 您需要使用以下内容进行设置: -

RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

您可以根据需要修改上述代码。

答案 1 :(得分:0)

我不知道为什么会这样,但错误是我必须收到@RequestBody作为TblGps []数组而不是单个对象!

虽然我之前已经获取并接收了相同的对象并将结果作为单个对象接收,然后我将其发布回服务器,并将其作为对象数组接收...是否有线?

是否有人对此行为有解释?

    TblGps gps = (TblGps) restTemplate.getForObject(urlGET,TblGps.class);


 // alter the Object Data


 gps.setDescr("success");

      //POST Object to Service Endpoint
      TblGps gpsResult = restTemplate.postForObject(urlPOST, "POST", TblGps.class, gps);

和我的控制器代码

 @RequestMapping(value="/TblGps/update", method=RequestMethod.POST, consumes = "application/json",produces="application/json")
      @ResponseBody public TblGps postSingleObject(@RequestBody  TblGps[] gps){

            logger.debug("/TblGps/update: " + gps[0].getId());

              return Application.DataRepository.save(gps[0]);
        }

答案 2 :(得分:0)

以下对我来说非常有用,

    RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
    List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
    interceptors.add(new LoggingRequestInterceptor());
    restTemplate.setInterceptors(interceptors );
    String uri = "*********************";

    List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
    messageConverters.add(new MappingJacksonHttpMessageConverter());
    restTemplate.setMessageConverters(messageConverters); 

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.set("Authorization","Bearer "+"***************************");


    Folder folder=new Folder();
    folder.setName("subFolder1");
    Parent parent = new Parent();
    parent.setId("6753425702");
    folder.setParent(parent);
    HttpEntity<Object> entity = new HttpEntity<Object>(folder,headers);

    ResponseEntity<Result> result =    restTemplate.exchange(uri,HttpMethod.POST,entity,Result.class);