Java发送带JSON的HTTP POST请求返回400 Bad Request问题求助
问题排查及修复方案
已定位的问题点
- 请求头
Fiware-Service的值存在多余前置空格:两处设置的" myHome"前面有一个空格,Fiware平台对服务头校验严格,非法的头格式会直接返回400错误 - POST请求缺少错误响应读取逻辑:400属于异常状态码,直接调用
getInputStream()会抛出IO异常,无法获取服务端返回的具体错误提示,无法进一步定位问题 - 变量命名冲突:类级别定义了静态
HttpURLConnection connection,两个请求方法中又分别定义了同名局部变量,容易出现资源泄漏、请求状态串用的问题 - 手动拼接JSON字符串存在隐患:虽然当前JSON格式无误,但后续修改容易出现转义错误、语法错误
修复步骤
- 修正
Fiware-Service请求头,删除值前面的空格,将两处的" myHome"修改为"myHome" - 给POST请求添加状态码判断逻辑,异常状态下读取错误流获取具体报错信息,参考GET请求的处理逻辑
- 删除类级别定义的静态
HttpURLConnection connection变量,所有连接对象使用方法内局部变量即可 - (可选优化)使用Jackson、Gson等JSON序列化库生成请求JSON,避免手动拼接的语法问题
核心修改代码示例
修改后的PostRequest方法
public void PostRequest() throws IOException { //set the url String url = "http://192.168.0.104:4041/iot/devices"; URL obj = new URL(url); //open the connection HttpURLConnection connection = (HttpURLConnection) obj.openConnection(); //set the method type(POST OR GET) connection.setRequestMethod("POST"); //set the request properties(headers etc.) connection.setRequestProperty("Content-Type", "application/json; utf-8"); connection.setRequestProperty("Accept", "application/json"); // 修复头的多余空格 connection.setRequestProperty("Fiware-Service","myHome"); connection.setRequestProperty("Fiware-ServicePath","/environment"); //make sure that will be able to write content to the connection output stream connection.setDoOutput(true); //Json formatted input string String jsonInputString = "{\n" + " \"devices\": [\n" + " {\n" + " \"device_id\": \"sensor01\",\n" + " \"entity_name\": \"LivingRoomSensor\",\n" + " \"entity_type\": \"multiSensor\",\n" + " \"attributes\": [\n" + " { \"object_id\": \"t\", \"name\": \"Temperature\", \"type\": \"celsius\" },\n" + " { \"object_id\": \"l\", \"name\": \"Luminosity\", \"type\": \"lumens\" }\n" + " ]\n" + " }\n" + " ]\n" + "}"; try(OutputStream os = connection.getOutputStream()) { byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } // 新增状态码判断逻辑,获取错误提示 int status = connection.getResponseCode(); BufferedReader reader; StringBuilder response = new StringBuilder(); if (status > 299) { reader = new BufferedReader(new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8)); } else { reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)); } String responseLine = null; while ((responseLine = reader.readLine()) != null) { response.append(responseLine.trim()); } reader.close(); //print the result System.out.println(response.toString()); }
内容的提问来源于stack exchange,提问作者Nedislav Kolev
相关产品推荐
相关产品推荐

