HttpClient一 get post的无参及带表单参数和请求头的请求与接收

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/uotail/article/details/86111356

目录

 

背景

idea新建maven项目引入jar包

quickstart

使用原生java获取urlStr页面源码并打印响应头和结果

get无参请求返回网页源码

get无参请求获取网页源码写入D盘

get请求设置请求时间配置

get请求传递表单参数1

请求发送

http get请求接收方法

get 带表单参数和头信息请求方式2 (两种方法)

post 请求 带表单参数和请求头

Entity-StringEntity 和 UrlEncodedFormEntity


背景

官网 http://hc.apache.org/httpclient-3.x/
Commons HttpClient项目现已结束,不再开发。它已被HttpClientHttpCore模块中的Apache HttpComponents项目取代,它提供了更好的性能和更大的灵活性。

我们先从HttpCore开始学习

idea新建maven项目引入jar包

需要引入httpclient和fastjson的依赖

   <dependencies>
        <!--http://hc.apache.org/httpcomponents-client-ga/httpclient/dependency-info.html-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.7</version>
        </dependency>
    </dependencies>

quickstart

来源 http://hc.apache.org/httpcomponents-client-ga/quickstart.html

    public static void main() throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            /**
             * get的请求方式
             */
            HttpGet httpGet = new HttpGet("http://httpbin.org/get");
            CloseableHttpResponse response1 = httpclient.execute(httpGet);
            // The underlying HTTP connection is still held by the response object
            // to allow the response content to be streamed directly from the network socket.
            //底层HTTP连接仍由响应对象保存,它允许直接从网络套接字流式传输响应内容。
            // In order to ensure correct deallocation of system resources
            // the user MUST call CloseableHttpResponse#close() from a finally clause.
            //为了确保正确释放系统资源,用户必须从finally子句中调用CloseableHttpResponse#close()
            // Please note that if response content is not fully consumed the underlying
            // connection cannot be safely re-used and will be shut down and discarded
            // by the connection manager.
            //请注意,如果响应内容没有完全消耗,那么底层连接无法安全重复使用,将被连接管理器关闭并丢弃
            try {
                System.out.println(response1.getStatusLine());
                HttpEntity entity1 = response1.getEntity();
                // do something useful with the response body
                // and ensure it is fully consumed
                EntityUtils.consume(entity1);
            } finally {
                response1.close();
            }

            /**
             * post 请求方式 并携带表单参数
             */
            HttpPost httpPost = new HttpPost("http://httpbin.org/post");
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("username", "vip"));
            nvps.add(new BasicNameValuePair("password", "secret"));
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            CloseableHttpResponse response2 = httpclient.execute(httpPost);

            try {
                System.out.println(response2.getStatusLine());
                HttpEntity entity2 = response2.getEntity();
                // do something useful with the response body
                // and ensure it is fully consumed
                //对响应主体做一些有用的事情并确保它被完全被消费
                EntityUtils.consume(entity2);

            } finally {
                response2.close();
            }

        } finally {
            httpclient.close();
        }
    }

使用原生java获取urlStr页面源码并打印响应头和结果

/**
	 * 使用原生java获取urlStr页面源码并打印响应头和结果
	 * @param urlStr
	 * @return
	 */
	public static String sendGetByJava(String urlStr) {
		String result = "";
		BufferedReader in = null;
		try{
			URL url = new URL(urlStr);
			URLConnection connection = url.openConnection();
			connection.setRequestProperty("accept", "*/*");//接受任何 MIME 类型的资源
			connection.setRequestProperty("connection", "Keep-Alive");//http连接为长连接
			connection.connect();
			Map<String, List<String>> map = connection.getHeaderFields();
			Set<Map.Entry<String, List<String>>> entries = map.entrySet();
			for (Map.Entry<String, List<String>> entry : entries) {
				System.out.println(entry.getKey()+"-"+entry.getValue());
			}
			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();
				}
			} catch (Exception e2){
				e2.printStackTrace();
			}
		}
		return result;
	}

get无参请求返回网页源码


	/**
	 * get方式获取url页面源码
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public static String getHtmlStr(String url) throws Exception {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpGet get = new HttpGet(url);
		String htmlStr = "";
		HttpResponse response = httpClient.execute(get);
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode == 200) {
			//htmlStr = EntityUtils.toString(response.getEntity());//中文乱码
			htmlStr = EntityUtils.toString(response.getEntity(), "UTF-8");
		}
		try {
			httpClient.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return htmlStr;
	}

get无参请求获取网页源码写入D盘

 public static  void main() throws IOException {
        //使用HttpClient进行网络处理的基本步骤
        //1、通过get的方式获取到Response对象。
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("http://www.baidu.com/");
        CloseableHttpResponse response = httpClient.execute(httpGet);
        //注意,必需要加上http://的前缀,否则会报:Target host is null异常。

        //2、获取Response对象的Entity
        HttpEntity entity = response.getEntity();
        System.out.println(entity);

        //3、通过Entity获取到InputStream对象,然后对返回内容进行处理
        InputStream content = entity.getContent();
        Scanner scanner = new Scanner(content);
        String filename = "D://1.txt";

        Writer writer = new PrintWriter(filename);
        while (scanner.hasNext()){
            //System.out.println(scanner.nextLine());
            writer.write(scanner.nextLine());
        }
        writer.close();//如果此输出流不关闭则数据不会从流中刷到硬盘中
        //注意:直接将HttpGet改为HttpPost,返回的结果有误,百度返回302状态,即重定向,新浪返回拒绝访问。怀疑大多网站均不允许POST方法直接访问网站。
    }

get请求设置请求时间配置

post类似

    //httpclient的请求配置主要是通过RequestConfig封装,然后通过httpGet.setConfig(config);把RequestConfig对象传进来
    //https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/config/RequestConfig.html
    public static void main() throws IOException {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建http GET请求
        HttpGet httpGet = new HttpGet("http://www.baidu.com/");
        // 构建请求配置信息
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(1000)          //创建连接的最长时间
                .setConnectionRequestTimeout(500) //从连接池中获取到连接的最长时间
                .setSocketTimeout(10 * 1000)      //数据传输的最长时间  socket读数据超时时间:从服务器获取响应数据的超时时间
                .build();
        // 设置请求配置信息
        httpGet.setConfig(config);
        CloseableHttpResponse response = null;
        try {
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                //// 使用Apache提供的工具类进行转换成字符串
                String content = EntityUtils.toString(response.getEntity(), "UTF-8");
                System.out.println(content);
            }
        } finally {
            if (response != null) {
                response.close();
            }
            httpclient.close();
        }
    }

get请求传递表单参数1

请求发送

public static void main() throws IOException{
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse=null;
        InputStream is = null;
        //String url="https://127.0.0.1:8080/httpByGetParams";
        //前缀不要为https 否则报错 
        //javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
        String url="http://127.0.0.1:8080/httpByGetParams";

        //封装请求参数
        List<NameValuePair> params = new ArrayList<>();
        BasicNameValuePair basicNameValuePair1 = new BasicNameValuePair("name", "改革开放");
        BasicNameValuePair basicNameValuePair2 = new BasicNameValuePair("age", "30");
        params.add(basicNameValuePair1);
        params.add(basicNameValuePair2);
        String str="";

        try{
            //转换为键值对
            str=EntityUtils.toString(new UrlEncodedFormEntity(params,Consts.UTF_8));
            System.out.println(str);

            //创建get请求
            HttpGet httpGet = new HttpGet(url+"?"+str);
            //执行get请求
            httpResponse = httpClient.execute(httpGet);
            //得到响应体
            HttpEntity entity = httpResponse.getEntity();
            if(entity!=null){
                is=entity.getContent();

                //转换为字节输入流
                BufferedReader br = new BufferedReader(new InputStreamReader(is, Consts.UTF_8));
                String body=null;
                while ((body=br.readLine())!=null){
                    System.out.println(body);
                }

            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭输入流
            if(is!=null){
                try {
                    is.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

            //消耗实体内容
            if(httpResponse!=null){
                try {
                    httpResponse.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            //丢弃http连接
            if(httpClient!=null){
                try {
                    httpClient.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

http get请求接收方法

新建 spring boot 项目,直接在启动类上面写方法并启动


@RestController
@SpringBootApplication
@MapperScan("com.whale.luo.mydemo")
public class MydemoApplication {

    @GetMapping("httpByGetParams")
    public void httpByGetParams(HttpServletRequest request){
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {//传递json数据的时候request是没有表单参数的
            String parameterName = parameterNames.nextElement();
            System.out.println(parameterName + "===" + request.getParameter(parameterName));
            //System.out.println(parameterNames.nextElement()+"=="+request.getParameter(parameterNames.nextElement()));
        }
    }

    public static void main(String[] args) {
        SpringApplication.run(MydemoApplication.class, args);
    }
}

application.yml

server:
  port: 8080

运行http get 请求这个页面打印如下参数

在这里插入图片描述

get 带表单参数和头信息请求方式2 (两种方法)

    public static void main() throws IOException {
           // 获取连接客户端工具
           CloseableHttpClient httpClient = HttpClients.createDefault();
           String entityStr = null;
           CloseableHttpResponse response = null;
           try {
               /*
                * 由于GET请求的参数都是拼装在URL地址后方,所以我们要构建一个URL,带参数
                */
               URIBuilder uriBuilder = new URIBuilder("http://127.0.0.1:8080/httpByGetParams");
               //第一种添加参数的形式
               //uriBuilder.addParameter("name", "root");
               //uriBuilder.addParameter("password", "123456");


               //第二种添加参数的形式
               List<NameValuePair> list = new LinkedList<>();
               BasicNameValuePair param1 = new BasicNameValuePair("name", "root");
               BasicNameValuePair param2 = new BasicNameValuePair("password", "123456");
               list.add(param1);
               list.add(param2);
               uriBuilder.setParameters(list);

               // 根据带参数的URI对象构建GET请求对象
               HttpGet httpGet = new HttpGet(uriBuilder.build());
               System.out.println(httpGet.getURI());//http://127.0.0.1:8080/httpByGetParams?name=root&password=123456
               /*
                * 添加请求头信息
                */
               // 浏览器表示
               httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
               // 传输的类型
               httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded");

               // 执行请求
               response = httpClient.execute(httpGet);
               // 获得响应的实体对象
               HttpEntity entity = response.getEntity();
               // 使用Apache提供的工具类进行转换成字符串
               entityStr = EntityUtils.toString(entity, "UTF-8");
           } catch (ClientProtocolException e) {
               System.err.println("Http协议出现问题");
               e.printStackTrace();
           } catch (ParseException e) {
               System.err.println("解析错误");
               e.printStackTrace();
           } catch (URISyntaxException e) {
               System.err.println("URI解析异常");
               e.printStackTrace();
           } catch (IOException e) {
               System.err.println("IO异常");
               e.printStackTrace();
           } finally {
               // 释放连接
               if (null != response) {
                   try {
                       response.close();
                       httpClient.close();
                   } catch (IOException e) {
                       System.err.println("释放连接出错");
                       e.printStackTrace();
                   }
               }
           }
           // 打印响应内容
           System.out.println(entityStr);

          /*因为GET请求的参数都是拼装到URL后面进行传输的,所以这地方不能直接添加参数,
              需要组装好一个带参数的URI传递到HttpGet的构造方法中,构造一个带参数的GET请求。
              构造带参数的URI使用URIBuilder类。
            上面添加请求参数的方法有两种,建议后者,后者操作更加灵活。*/
       }

http接收 共用完善上面已有的接收方法

 @GetMapping("httpByGetParams")
    public void httpByGetParams(HttpServletRequest request){
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {//传递json数据的时候request是没有表单参数的
            String parameterName = parameterNames.nextElement();
            System.out.println(parameterName + "===" + request.getParameter(parameterName));
            //System.out.println(parameterNames.nextElement()+"=="+request.getParameter(parameterNames.nextElement()));
        }
      //打印请求头
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String headerName = headerNames.nextElement();
            System.out.println(headerName+"=="+request.getHeader(headerName));
        }
    }

打印结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190109002201631.png

post 请求 带表单参数和请求头

接收方法
在 spring boot 启动类上加方法

   @PostMapping("httpByPostParams")
    public void httpByPostParams(HttpServletRequest request){
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {//传递json数据的时候request是没有表单参数的
            String parameterName = parameterNames.nextElement();
            System.out.println(parameterName + "===" + request.getParameter(parameterName));
            //System.out.println(parameterNames.nextElement()+"=="+request.getParameter(parameterNames.nextElement()));
        }

        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String headerName = headerNames.nextElement();
            System.out.println(headerName+"=="+request.getHeader(headerName));
        }
    }

post请求

public static void test7() {
        // 获取连接客户端工具
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String entityStr = null;
        CloseableHttpResponse response = null;
        try {
            // 创建POST请求对象
            //HttpPost httpPost = new HttpPost("http://www.baidu.com");
            HttpPost httpPost = new HttpPost("http://127.0.0.1:8080/httpByPostParams");
            /*
             * 添加请求参数
             */
            // 创建请求参数
            List<NameValuePair> list = new LinkedList<>();
            BasicNameValuePair param1 = new BasicNameValuePair("name", "root");
            BasicNameValuePair param2 = new BasicNameValuePair("password", "123456");
            BasicNameValuePair param3 = new BasicNameValuePair("data", "dataStr");
            list.add(param1);
            list.add(param2);
            list.add(param3);
            // 使用URL实体转换工具
            //HttpEntity reqEntity = new UrlEncodedFormEntity(formparams, "utf-8");
            UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8");
            httpPost.setEntity(entityParam);

            /*
             * 添加请求头信息
             */
            // 浏览器表示
            httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
            // 传输的类型
            httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");

            // 执行请求
            response = httpClient.execute(httpPost);
            // 获得响应的实体对象
            HttpEntity entity = response.getEntity();
            // 使用Apache提供的工具类进行转换成字符串
            entityStr = EntityUtils.toString(entity, "UTF-8");
            // System.out.println(Arrays.toString(response.getAllHeaders()));
        } catch (ClientProtocolException e) {
            System.err.println("Http协议出现问题");
            e.printStackTrace();
        } catch (ParseException e) {
            System.err.println("解析错误");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("IO异常");
            e.printStackTrace();
        } finally {
            // 释放连接
            if (null != response) {
                try {
                    response.close();
                    httpClient.close();
                } catch (IOException e) {
                    System.err.println("释放连接出错");
                    e.printStackTrace();
                }
            }
        }

        // 打印响应内容
        System.out.println(entityStr);
    }

在这里插入图片描述
参考
https://blog.csdn.net/YouCanYouUp_/article/details/80769572
https://blog.csdn.net/wo18237095579/article/details/80482027

Entity-StringEntity 和 UrlEncodedFormEntity

 static  void testEntity() throws IOException {
        Map<String,Object> mapParams = new HashMap<>();
        mapParams.put("username","wh");
        mapParams.put("password","ale");
        StringEntity stringEntity = new StringEntity(JSONObject.toJSONString(mapParams),ContentType.APPLICATION_JSON);
        System.out.println(EntityUtils.toString(stringEntity));//{"password":"ale","username":"wh"}
        StringEntity stringEntity1 = new StringEntity(JSONObject.toJSONString(mapParams));//{"password":"ale","username":"wh"}
        System.out.println(EntityUtils.toString(stringEntity1));
    }
  1. UrlEncodedFormEntity()
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
 
NameValuePair pair1 = new BasicNameValuePair("supervisor", supervisorEt.getEditableText().toString());
NameValuePair pair2 = new BasicNameValuePair("content", superviseContentEt.getEditableText().toString());
NameValuePair pair3 = new BasicNameValuePair("userId", String.valueOf(signedUser.getId()));
 
pairs.add(pair1);
pairs.add(pair2);
pairs.add(pair3);
 
httpPost.setEntity(new UrlEncodedFormEntity(pairs, HTTP.UTF_8)) 

  1. StringEntity()
JSONObject postData = new JSONObject();
 
postData.put("supervisor", supervisorEt.getEditableText().toString());
postData.put("content", superviseContentEt.getEditableText().toString());
postData.put("userId", signedUser.getId());
 
httpPost.setEntity(new StringEntity(postData.toString(), HTTP.UTF_8)); 

可以看出,UrlEncodedFormEntity()的形式比较单一,只能是普通的键值对,局限性相对较大。
而StringEntity()的形式比较自由,只要是字符串放进去,不论格式都可以。
https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/HttpEntity.html
https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/entity/StringEntity.html

下一篇在此基础上讲post json数据的 请求与接收

猜你喜欢

转载自blog.csdn.net/uotail/article/details/86111356