需求背景:负责调用一个外部接口,请求方式为post,内容类型为x-www-form-urlencoded。
开发方式:测试驱动开发,使用curl验证接口,测试成功。主要是构造参数,完成测试后直接在代码中使用。
curl -X POST \
https://test.demo.com/msg/rest/send \
-H 'Authorization: manonxiaomai' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'cache-control: no-cache' \
-d 'timestamp=1621816295&¶mJson=%7B%22msgType%22%3A%22text%22%2C'
开发代码:使用Java HttpURLConnection进行url连接,然后使用OutputStream写出参数。
private static String createHttpReq(String urlStr, String data, String method) {
URL url = null;
HttpURLConnection conn = null;
PrintWriter print = null;
String result = "";
try {
url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Content-Type", "x-www-form-urlencoded;charset=utf-8");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("cache-control", "no-cache");
conn.setRequestProperty("Authorization", "manonxiaomai");
conn.setConnectTimeout(3000);
conn.setReadTimeout(3000);
if ("post".equalsIgnoreCase(method)) {
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
} else {
conn.setRequestMethod("GET");
}
conn.setDoInput(true);
conn.connect();
if ("post".equalsIgnoreCase(method)) {
print = new PrintWriter(conn.getOutputStream());
print.print(data);
print.flush();
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
result = bufferedReader.readLine();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (print != null) {
try {
print.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return result;
}
问题发现:Java程序运行后发现服务端返回参数为null的校验错误,怀疑是请求头信息不正确,仔细查看发现内容类型赋值不正确。
错误:conn.setRequestProperty("Content-Type", "x-www-form-urlencoded;charset=utf-8");
正确:conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
解决办法:对于固定类型的值建议使用框架中自带的枚举值,或自己维护枚举值或常量,不要手写。