Java 使用GET和POST方式提交HttpURLConnection请求

      Java调用接口进行获取对方服务器的数据在开发中特别常见,在实际开发过程中,很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信、天气等)或者测试自己写的接口。

      那么Java如何调用接口?==》通过 HttpURLConnection建立实际的连接,交换数据。

 

     URLEncoder 和 URLDecoder用于完成普通字符串和 application/x-www-form-urlencoded MIME字符串之间的相互转换.

在发送端端,这样设置参数:编码:"UTF-8"

String content = "字段名1=" + URLEncoder.encode("字符串值1", "编码")+"&字段名2=" + URLEncoder.encode("字符串值2", "编码");

在接收端,这样获取参数:

String name = request.getParameter("account");
String pswd = request.getParameter("pswd"); 
System.out.println(new String(name.getBytes("iso-8859-1"),"UTF-8"));
System.out.println(new String(pswd.getBytes("iso-8859-1"),"UTF-8"));

 

一、 使用GET方式和POST提交HttpURLConnection请求

     这里简单创建两个springboot的项目 ,编码使用UTF-8,做测试,对于使用输入流和输出流的那种处理流,自己选择。

1、HttpURLUtil的模板工具类

步骤:

  • 1)URL url= new URL(url);
  • 2)获取connection,并设置相应的请求属性。特别注意设置对应的GET/POST请求方式,Content-Type的数据类型,参数的形式
  • 3)建立实际的连接,通过输入输出流的方式交换数据
  • 4)最后,关闭流和关闭连接connection。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;


public class HttpURLUtil {
    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url   发送请求的URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        HttpURLConnection connection = null;
        try {
            URL getUrl = new URL(url + "?" + param);
            // 打开和URL之间的连接
            connection = (HttpURLConnection) getUrl.openConnection();

            // 在connect之前,设置通用的请求属性
            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.setRequestProperty("Charsert", "UTF-8");

            // 配置本次连接的Content-type,form表单是"application/x-www-form-urlencoded",json是"application/json"等
            // 根据需求自己调整Content-type
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);
            // 设置连接方式:get
            connection.setRequestMethod("GET");
            // 建立实际的连接,可不写,注意connection.getOutputStream会隐含的进行connect。
            connection.connect();

            // 获取所有响应头字段
            Map> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }

            // 定义BufferedReader输入流来读取URL的响应
            if (connection.getResponseCode() == 200) {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (connection != null) {
                    //关闭连接
                    connection.disconnect();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        String result = "";
        PrintWriter out = null;
        BufferedReader in = null;
        HttpURLConnection connection = null;
        try {
            URL postUrl = new URL(url);
            // 打开和URL之间的连接
            connection = (HttpURLConnection) postUrl.openConnection();

            // 在connect之前,设置通用的请求属性
            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.setRequestProperty("Charsert", "UTF-8");

            connection.setConnectTimeout(15000);
            connection.setReadTimeout(60000);
            // 发送POST请求必须设置如下两行,参数要放在http正文内
            connection.setDoOutput(true);
            connection.setDoInput(true);
            // 默认是 GET方式
            connection.setRequestMethod("POST");
            // Post 请求不使用缓存
            connection.setUseCaches(false);
            // 配置本次连接的Content-type,form表单是"application/x-www-form-urlencoded",json是"application/json"等
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.connect();

            // 参数要放在http正文内
            //1.获取URLConnection对象对应的输出流
            out = new PrintWriter(connection.getOutputStream());
            //2.中文有乱码的需要将PrintWriter改为如下
            //out=new OutputStreamWriter(conn.getOutputStream(),"UTF-8")
            out.print(param);
            out.flush();
           //也可以使用DataOutputStream 
//          DataOutputStream dos=new DataOutputStream(httpConn.getOutputStream());
//          dos.writeBytes(param);
//          dos.flush();
//          dos.close();

            // 定义BufferedReader输入流来读取URL的响应
            if (connection.getResponseCode() == 200) {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!" + e);
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
                if (connection != null) {
                    //关闭连接
                    connection.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

}

2、两个项目中的controller测试:

     中文乱码这里也做了数据

    @GetMapping("/sendHttpURL")
    @ResponseBody
    public String sendHttpURL() throws UnsupportedEncodingException {
        //发送 GET 请求
        String paramGet =  "v1=123456"+"&v2=" + URLEncoder.encode("发送 GET 请求", StandardCharsets.UTF_8.name());
        String s = HttpURLUtil.sendGet("http://127.0.0.1/sbt_javademo/receiveURLGet", paramGet);
        System.out.println(s);

        //发送 POST 请求
//        String paramPost =  "v3=45678"+"&v4=" + URLEncoder.encode("发送 POST 请求", StandardCharsets.UTF_8.name());
        String paramPost =  "v3=45678"+"&v4=发送 POST 请求";
        String sr = HttpURLUtil.sendPost("http://127.0.0.1/sbt_javademo/receiveURLPost", paramPost);
        System.out.println(sr);

        return s + "\n" + sr;
    }
    @GetMapping("/receiveURLGet")
    @ResponseBody
    public ResponseEntity> receiveURLGet(String v1, String v2) {
        System.out.println("v1:" + v1 + " == v2:" + v2);
        Map map = new HashMap<>();
        map.put("code", 20000);
        map.put("data", "接受 GET 请求");
        return ResponseEntity.ok(map);
    }
    @PostMapping("/receiveURLPost")
    @ResponseBody
    public ResponseEntity> receiveURLPost(HttpServletRequest request, String v3, String v4) {
        System.out.println("v3:" + v3 + " == v4:" + v4);
        Map map = new HashMap<>();
        map.put("code", 20000);
        map.put("data", "接受 POST 请求");
        return ResponseEntity.ok(map);
    }

3、结果内容:

     这里 Content-Type的类型,都使用的是表单“application/x-www-form-urlencoded”,根据需求自己调整

     Java 使用GET和POST方式提交HttpURLConnection请求_第1张图片

4、参数不是八大基本类型时

     一般我会使用标准json字符串(map封装)来传参,接受端通过request获取流的形式处理。 post提交为例

    1)传参为List 类型:

List list= new ArrayList<>();
list.add("123人");
list.add("ren人");
list.add("人14周岁");

Map tagNameMap = new HashMap<>();
tagNameMap.put("list", list);
String jsonString = JSON.toJSONString(tagNameMap);

String result= this.sendPost(url, jsonString);

   2)接收端:

    @PostMapping(value = "/getList")
    @ResponseBody
    public ResponseEntity getList(HttpServletRequest request){
        try (
                BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream()));
        ){
            StringBuilder data = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null) {
                data.append(line);
            }
            if(data != null){
                Map map = (Map) JSON.parse(data.toString());
                String listStr= map.get("tagNames").toString();
                System.out.println(listStr);
                List list = JSONObject.parseArray(listStr, String.class);
                list.forEach(System.out::println);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        return ResponseEntity.ok("success");
    }

 

对于一些知识点进行整理和归纳,这样容易对比加深记忆,总结:

1)HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。

     无论是post还是get,实际上直到HttpURLConnection的getInputStream()这个函数调用时才正式发送出去。

2)设置请求属性必须在connect()方法执行之前完成。

     对于post中,将参数放入http正文中(outputStream的写操作)必须要在inputStream()方法读操作之前完成。

     这些顺序实际上是由http请求的格式决定的。    

http请求实际上由两部分组成,

    一个是http头,所有关于此次http请求的配置都在http头里面定义。

    一个是正文content。

connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,就必须把所有的配置准备好。     

在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,    实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中,直到outputStream流关闭时或者显示调用flush()方法,才会生成http正文。至此,http请求的东西已经全部准备就绪。

在调用getInputStream()方法时,就会把准备好的http请求(包括http头和正文)正式发送到服务器,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。

 

二、请求及属性的一些知识点

     Java 使用GET和POST方式提交HttpURLConnection请求_第2张图片

1、HttpServletRequset和HttpServletResponse的知识点:

     Servlet的继承体系与HttpServletRequset和HttpServletResponse

2、Request的相关方法:

getContextPath():这个方法返回的是web应用映射的虚拟目录地址:如ServletDemo应用的虚拟目录是:/ServletDemo

getCookies():这个方法返回的是一个Cookies[],因为用户在请求的时候会携带很多的cookie,关于Cookie的相关知识

getHeader(String name)/getIntHeader(String name)/getDateHeader(String name):
这些方法是获取请求头信息的,只是针对不同的类型的,有字符串类型的,时间类型,数值类型的

getHeaderNames():这个方法是获取所有请求头的字段名称

getHeaders(String name):这个方法是获取一个请求头字段的所有值,因为有时候可能会有相同请求头字段信息,不会覆盖的

getMethod():这个方法是获取客户机的请求方法

getQueryString():这个方法是获取用户请求时的查询参数的,即url后面携带的参数

getRequestSessionId():这个方法是获取客户机在请求的时候携带的sessionid值,有关session的相关知识,后面会详解

getRequestURL():这个方法是获取客户机请求的url

getServletPath():这个方法返回的是请求的Servlet的映射路径,比如:ServletRequest映射的是是/ServletRequest

getServerName()/getServerPort():这两个方法是获取服务器的名称和端口号,比如localhost,8080

getSession()/getSession(boolean mode):这两个方法是获取一个session对象,相关之后在session篇会说到

getAttribute(String name):这个方法是从Request域中获取值

getAttributeNames():这个方法是获取Request域中获取所有的字段名称

getParameter(String name):这个方法是获取用户使用get/post方式携带的参数值

getParameterNames():这个方法是获取用户请求时携带的所有参数名称

getParameterMap():这个方法是获取用户请求时携带的参数名称和参数值,并将其组装成一个Map对象

getParameterValues():这个方法是获取用户请求携带的参数值,因为有时候一个参数名称可能对应多个值

setAttribute(String name,Object value):这个方法是设置Request域中的属性值

removeAttribute(String name):这个方法是删除Request域中的属性值

getInputStream()/getReader():
这个方法是获取用户请求的时候上传的输入流,比如我们在处理用户上传文件的时候。需要用到这个输入流

setCharacterEncoding(String name):这个方法是设置Request容器的编码

getRemoteAddr()/getRemoteHost():获取客户机的IP地址和主机名

getProctocol():获取协议名称

getRequestDispatcher(String path):获取一个转发对象RequestDispatcher,进行转发操作

 

ends~

你可能感兴趣的:(Common,使用GET和POST方式)