文章目录
前言一、工具类与Controller层1.1 远程调用请求工具类1.2 Controller 层代码1.3 R 响应对象 二、GET请求2.1 get 请求测试2.2 报错与解决2.3 改进后代码2.4 测试结果 三、POST请求3.1 post 请求测试3.2 BodyBo 对象3.2 测试结果前言
在实际开发过程中我们可能需要在代码中发送请求,调用第三方接口,所以我们需要编写工具类调用 HTTP 请求。此文章记录常见的代码中调用 POST 和 GET 请求以及用于接收他们返回结果的工具类。 以及记录报错信息:java.io.IOException: Server returned HTTP response code: 400 for URL:
一、工具类与Controller层
1.1 远程调用请求工具类
@Componentpublic class HttpRequest {/*** @param url 发送请求的 URL* @return 所代表远程资源的响应结果*/public static String sendGet(String url) {String result = "";BufferedReader in = null;try {URL realUrl = new URL(url);// 打开和URL之间的连接URLConnection connection = realUrl.openConnection();// 设置通用的请求属性connection.setRequestProperty("accept", "*/*");connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 建立实际的连接connection.connect();// 获取所有响应头字段Map<String, List<String>> map = connection.getHeaderFields();in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {e.printStackTrace();} finally {try {if (in != null) {in.close();}} catch (Exception e2) {e2.printStackTrace();}}return result;}/*** @param url 发送请求的 URL* @param param 请求参数,post请求参数是以json的形式发送。* @return 所代表远程资源的响应结果*/public static String sendPost(String url, String param) {OutputStreamWriter out = null;BufferedReader in = null;String result = "";try {URL realUrl = new URL(url);HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");conn.setDoOutput(true);conn.setDoInput(true);out = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);out.write(param);out.flush();in = new BufferedReader(new InputStreamReader(conn.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {e.printStackTrace();}finally {try {if (out != null) {out.close();}if (in != null) {in.close();}} catch (IOException ex) {ex.printStackTrace();}}return result;}/*** 获取返回json串中的data对象* @param source http请求返回的json串* @param clazz 返回类型字节码对象* @param <T> 返回数据类型* @return*/public static <T> T dataString2Array(String source, Class<T> clazz){JSONObject jsonObject = JSONObject.parseObject(source);if(!jsonObject.containsKey("data")){return null;}String data = jsonObject.get("data").toString();return JSON.parseObject(data, clazz);}/*** 获取返回json串中的list对象* @param source http请求返回的json串* @param clazz 返回类型字节码对象* @param <T> 返回数据类型* @return*/public static <T> List<T> listString2Array(String source, Class<T> clazz) {JSONObject jsonObject = JSONObject.parseObject(source);if(!jsonObject.containsKey("list")||jsonObject.getJSONArray("list").isEmpty()){return null;}String list = jsonObject.get("list").toString();JSONArray jsonArray = JSONArray.parseArray(list);return JSON.parseArray(jsonArray.toString(), clazz);}}
1.2 Controller 层代码
@RestController@RequestMapping("test")public class HttpController {@GetMapping("/get")public R get(@RequestParam String name){List<String> list = new ArrayList<>();list.add(name);list.add(name + "-GET");list.add(name + "-TEST");return R.ok().put("list", list);}@PostMapping("/post")public R post(@RequestBody BodyBo bodyBo){BodyBo body = new BodyBo();body.setName(bodyBo.getName() + "你好!");body.setAge("你今年" + bodyBo.getAge() + "岁了!");System.out.println(body);return R.ok().put("data", body);}}
1.3 R 响应对象
public class R extends HashMap<String, Object> {private static final long serialVersionUID = 1L;public R() {put("code", 0);}public static R error() {return error(500, "未知异常,请联系管理员");}public static R error(String msg) {return error(500, msg);}public static R error(int code, String msg) {R r = new R();r.put("code", code);r.put("msg", msg);return r;}public static R ok(String msg) {R r = new R();r.put("msg", msg);return r;}public static R ok(Map<String, Object> map) {R r = new R();r.putAll(map);return r;}public static R ok() {return new R();}public R put(String key, Object value) {super.put(key, value);return this;}}
二、GET请求
2.1 get 请求测试
public static void main(String[] args) {System.out.println("================GET 请求测试==================");String getUrl = "http://127.0.0.1/test/get?name=" + "你好";String data = sendGet(getUrl);List<String> result = listString2Array(data, String.class);System.out.println("获取get请求的返回数据:" + result);}
2.2 报错与解决
================GET 请求测试==================java.io.IOException: Server returned HTTP response code: 400 for URL: http://127.0.0.1/test/get?name=你好at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.lang.reflect.Constructor.newInstance(Constructor.java:423)at .www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:1944)at .www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:1939)at java.security.AccessController.doPrivileged(Native Method)at .www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1938)at .www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1508)at .www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)at io.renren.utils.HttpRequest.sendGet(HttpRequest.java:42)at io.renren.utils.HttpRequest.main(HttpRequest.java:155)Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: http://127.0.0.1/test/get?name=你好at .www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)at .www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)at .www.protocol.http.HttpURLConnection.getHeaderFields(HttpURLConnection.java:3023)at io.renren.utils.HttpRequest.sendGet(HttpRequest.java:40)... 1 moreException in thread "main" java.lang.NullPointerExceptionat io.renren.utils.HttpRequest.listString2Array(HttpRequest.java:129)at io.renren.utils.HttpRequest.main(HttpRequest.java:156)
查阅资料后得知:是URL编码问题导致的,请求参数是中文。
1.URL 该编码的编码要编码,否则如果存在空格就会报400错误,那么什么样的URL 是该编码的呢?
URL 中有空格等特殊字符的URL 中有中文的
2.编码要只对参数编码,不要对整个 URL 进行编码因为如果对整个 URL 编码的话会把 URL 中的 /,& 等字符也进行编码了
3.使用 URLEncoder.encode(“param”,“charset”);
2.3 改进后代码
public static void main(String[] args) throws UnsupportedEncodingException {System.out.println("================GET 请求测试==================");String getUrl = "http://127.0.0.1/test/get?name=" + URLEncoder.encode("你好 !", "UTF-8");String data = sendGet(getUrl);List<String> result = listString2Array(data, String.class);System.out.println("获取get请求的返回数据:" + result);}
2.4 测试结果
三、POST请求
3.1 post 请求测试
public static void main(String[] args) throws UnsupportedEncodingException {System.out.println("================POST 请求测试==================");BodyBo bodyBo = new BodyBo();bodyBo.setAge("18");bodyBo.setName("SpringBoot 2.4.5 !");//post发送请求,需要将请求体设置成json字符串String json = JSONObject.toJSONString(bodyBo);String postUrl = "http://127.0.0.1:80/test/post";String post = sendPost(postUrl, json);System.out.println("post: " + post);BodyBo body = dataString2Array(post, BodyBo.class);System.out.println(body);}
3.2 BodyBo 对象
@Datapublic class BodyBo {private String name;private String age;}