Java Http请求工具类和接收请求的方法

本文深入解析HTTP协议中GET与POST请求的区别,包括数据传输方式、限制条件及如何使用Java实现这两种请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表面现像上面看看GET和POST的区别:


1.GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。

POST把提交的数据则放置在是HTTP包的包体中。


2."GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大量的数据,IIS4中最大为80KB,IIS5中为100KB"??!
 以上这句是我从其他文章转过来的,其实这样说是错误的,不准确的:

(1).首先是"GET方式提交的数据最多只能是1024字节",因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了。 而实际上, URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是 2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。

注意这是限制是整个URL长度,而不仅仅是你的参数值数据长度。[具体参考http://blog.youkuaiyun.com/somat/article/details/158707]


(2). 理论上讲,POST是没有大小限制的,HTTP协议规范也没有进行大小限制,说“POST数据量存在80K/100K的大小限制”是不准确的,POST数据是没有限制 的,起限制作用的是服务器的处理程序的处理能力。对于ASP程序,Request对象处理每个表单域时存在100K的数据长度限制。但如果使用 Request.BinaryRead则没有这个限制。   由这个延伸出去,对于IIS 6.0,微软出于安全考虑,加大了限制。我们还需要注意:
     1).IIS 6.0默认ASP POST数据量最大为200KB,每个表单域限制是100KB。
     2).IIS 6.0默认上传文件的最大大小是4MB。
     3).IIS 6.0默认最大请求头是16KB。
    IIS 6.0之前没有这些限制。[具体参考 http://blog.youkuaiyun.com/somat/article/details/158707]
所以上面的80K,100K可能只是默认值而已(注:关于IIS4和IIS5的参数,我还没有确认),但肯定是可以自己设置的。

由于每个版本的IIS对这些参数的默认值都不一样,具体请参考相关的IIS配置文档。


了解HTTP中GET和POST的区别请参考【http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html


此HTTPUtil工具类主要介绍怎么发送HTTP请求并附上获取请求参数的两种方式

import com.yjbq.common.StringUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Map;

public class HttpUtil {

    private HttpUtil() {
    }

    /**
     * 发送GET请求
     *
     * @param url 发送请求的URL
     * @param queryParas 参数集合
     * @return
     */
    public static String get(String url, Map<String, String> queryParas) {
        return get(url, queryParas, null);
    }

    /**
     * 发送GET请求
     *
     * @param url 发送请求的URL
     * @return 所代表远程资源的响应结果
     */
    public static String get(String url) {
        return get(url, null, null);
    }

    /**
     * 发送GET请求
     *
     * @param url 发送请求的URL
     * @param queryParas 参数集合
     * @param headers 头集合
     * @return 所代表远程资源的响应结果
     */
    public static String get(String url, Map<String, String> queryParas, Map<String, String> headers) {
        HttpURLConnection conn = null;
        try {
             //获取HttpURLConnection连接并设置参数
            conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), "GET", headers);
             // 建立HttpURLConnection实际的连接
            conn.connect();
            //返回  定义BufferedReader输入流来读取URL的响应
            return readResponseString(conn);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    /**
     * 发送POST请求
     *
     * @param url 发送请求的URL
     * @param data http请求包的包体
     * @param headers 头集合
     * @return 所代表远程资源的响应结果
     */
    public static String post(String url, String data, Map<String, String> headers) {
        return post(url, null, data, headers);
    }

    /**
     * 发送POST请求
     *
     * @param url 发送请求的URL
     * @param queryParas 请求参数(写在url后面的参数)如http://www.baidu.com?state=1&data=233
     * @param data http请求包的包体
     * @param headers 头集合
     * @return
     */
    public static String post(String url, Map<String, String> queryParas, String data, Map<String, String> headers) {
        HttpURLConnection conn = null;
        try {
            //获取HttpURLConnection连接并设置参数
            conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), "POST", headers);
            // 建立HttpURLConnection实际的连接
            conn.connect();
            // 获取URLConnection对象对应的输出流
            OutputStream out = conn.getOutputStream();
            // 发送请求参数
            out.write(data.getBytes("utf-8"));
            // flush输出流的缓冲
            out.flush();
            //关闭输出流
            out.close();
            //返回  定义BufferedReader输入流来读取URL的响应
            return readResponseString(conn);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    /**
     * 获取HttpURLConnection连接并设置参数
     *
     * @param url     发送请求的URL
     * @param method 请求方式(POST/GET)
     * @param headers 请求头
     * @return  所代表远程资源的响应结果
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     * @throws KeyManagementException
     */
    private static HttpURLConnection getHttpConnection(String url, String method, Map<String, String> headers) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
        //将url转变为URL对象
        URL _url = new URL(url);
        //打开URL连接
        HttpURLConnection conn = (HttpURLConnection) _url.openConnection();
        //设置请求方式
        conn.setRequestMethod(method);
        // 发送POST请求必须设置如下两行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        
        //连接时长
        conn.setConnectTimeout(20000);
        //读取时长
        conn.setReadTimeout(60000);

        // 设置通用的请求属性
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
      
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }
        return conn;
    }

    /**
     * 将参数和URL地址拼接
     *
     * @param url  发送请求的URL如http://www.baidu.com {"state":"1","data":"拼接Url"}
     * @param queryParas 传递的参数
     * @return
     */
    private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) {
        if (queryParas == null || queryParas.isEmpty()) {
            return url;
        }

        StringBuilder sb = new StringBuilder(url);
        boolean isFirst;
        //判断URL是否有 ?
        if (url.indexOf("?") == -1) {
            isFirst = true;
            sb.append("?");
        } else {
            isFirst = false;
        }
        //遍历请求参数
        for (Map.Entry<String, String> entry : queryParas.entrySet()) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append("&");
            }

            String key = entry.getKey();
            String value = entry.getValue();
            if (!StringUtil.isNull(value)) {
                //对value进行转码
                try {
                    value = URLEncoder.encode(value, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
            sb.append(key).append("=").append(value);
        }
        return sb.toString();
    }

    /**
     * 读取URL的响应
     *
     * @param conn HttpURLConnection对象
     * @return
     */
    private static String readResponseString(HttpURLConnection conn) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        try {
            //获取响应内容
            inputStream = conn.getInputStream();
            // 定义BufferedReader输入流来读取URL的响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 使用finally块来关闭输入流
        finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                }
            }
        }
    }
}

测试类HttpTest中getRequestData()方法提供了获取参数的两种方式具体见代码(此代码用的是JFinal框架继承了JFinal的Controller)并用到了fastjson-1.2.6.jar包。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.core.Controller;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletInputStream;

/**
 *
 * @author Administrator
 */
public class HttpTest extends Controller{
    public void getTest(){
        try {
            String s = getRequestData();
            System.out.println(s);
            JSONObject json = JSONObject.parseObject(s);
            System.out.println(json.getString("test"));
            renderJson(s);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    /**
     * 获取GET/POST请求提交的数据
     * @return 
     */
    public String getRequestData(){
        StringBuilder sb = new StringBuilder();
        try{
            //获取Http请求包的包体有两种方式getInputStream()、getReader(),因为GET方式请求一般不包含包体.一般用于POST请求获取参数.
            BufferedReader br = new BufferedReader(new InputStreamReader(getRequest().getInputStream()));
            //BufferedReader br = new BufferedReader(getRequest().getReader());
            String line;
            while((line = br.readLine())!=null){
                sb.append(line);
            }
        }catch(IOException e){
            System.out.println("getPostData Error: " + e.getLocalizedMessage());
            e.printStackTrace();
        }
        //如果包体没有值则获取url后面的参数
        if(sb.length() != 0){
            return sb.toString();
        }else{
            JSONObject json = new JSONObject();
            //JFinal获取url参数的方法
            Enumeration<String> names = getRequest().getParameterNames();
            //遍历参数
            while(names.hasMoreElements()){
                String key = names.nextElement();
                json.put(key, getPara(key));
            }
            return json.toString();
        }
    }
    
    public static void main(String[] args){
        Map<String, String> params = new HashMap<String, String>();
        params.put("num", "201");
        params.put("name", "李明");
        params.put("phone", "176****1828");

        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "application/json;charset=UTF-8");
        //请求参数附在URL后面的请求方式
        //String result = HttpUtil.post("http://地址:端口/httpTest/getTest", params, "", headers);
        //请求参数放在HTTP包的包体中
        String result = HttpUtil.post("http://地址:端口/httpTest/getTest",JSON.toJSONString(params),headers);
        System.out.println(result);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值