【问题标题】:Getting http 400 Bad Request Error with spring and resttemplate postForObject使用spring和resttemplate postForObject获取http 400错误请求错误
【发布时间】:2014-05-14 08:30:21
【问题描述】:

在执行对我的 Web 服务的 POST 调用时,我不断收到 Bad Request HttpClient 400 异常。 我无法弄清楚错误是源自客户端还是服务器端...请帮助我追踪此错误。但是由于使用 curl 的 pst 调用工作正常,我怀疑错误源于客户端的 springs resttemplate 构造

GET 调用工作正常! 使用 curl 的 post call 也可以正常工作

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 Bad Request Exception - GET 工作正常,使用 post 的 curl 命令行调用也在工作

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

}

【问题讨论】:

  • 为什么请求映射中有headers?这可能会导致问题,因为您已经拥有consumes
  • 你能添加那个异常的堆栈跟踪吗?我认为问题来自客户端,当它被添加到请求时,它没有正确转换 gps 变量。
  • 嗨,geoand,我已经尝试过请求映射中参数的不同值和不同值,但都给了我相同的错误请求错误 ....
  • @kamokaze71 可以发布正在发送到服务器的 json 吗?还有班级TblGps
  • 嗨,我已经发布了数据类文件。但是我怎样才能提取发送到服务器的json..?我需要spring源代码吗?你能告诉我怎么做吗?谢谢

标签: android spring rest webservice-client resttemplate


【解决方案1】:

似乎客户端没有正确设置 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);

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

【讨论】:

  • 为什么HttpEntity有“参数”作为key?
【解决方案2】:

我不知道为什么会这样,但错误是我必须将 @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]);
        }

【讨论】:

    【解决方案3】:

    以下对我来说非常有用,

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-28
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      相关资源
      最近更新 更多