springmvc http请求,支持get,post,附件传输和参数传输

主要解决http请求支持get,post,put,delete等常规方法,支持@RequestParam,@RequestBody,@PathVariable等参数格式传输,支持传输附件同时传递参数等,主体代码如下:

package mes.client.action;

import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import mes.client.pojo.po.CommonEntityPo;
import mes.client.pojo.vo.ResponseInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

public class MesMomConnectAction {

    private static Logger logger = LoggerFactory.getLogger(MesMomConnectAction.class);
    
    /**
     * 无请求体body,向指定URL发送方法的请求
     *
     * @param url   发送请求的URL
     * @return URL 所代表远程资源的响应结果
     */
    public static ResponseInfo getHttpParamReq(String url,String requestMethodType) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        HttpURLConnection connection = null;
        try {
            URL getUrl = new URL(url);
            // 打开和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");
            //添加必须的头部信息
            addHeader(connection);

            // 配置本次连接的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(requestMethodType);
            // 建立实际的连接,可不写,注意connection.getOutputStream会隐含的进行connect。
            connection.connect();

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }

            ResponseInfo responseInfo = JSON.parseObject(result.toString(), ResponseInfo.class);
            if(responseInfo.getStatusCode() == null){
                return getFailResponse(result.toString());
            }
            return responseInfo;
        } catch (Exception e) {
            logger.error("调用MES4.0接口异常",e);
            return getExceptionResponse(e);
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (connection != null) {
                    //关闭连接
                    connection.disconnect();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        
    }
    
    /** 
     * @description: get请求
     * @date: 2023-10-16 16:58:30 
     * @param url 
     * @return ResponseInfo 
     */
    public static ResponseInfo sendGet(String url){
        return getHttpParamReq(url,"GET");
    }

    /** 
     * @description:方法说明
     * @date: 2023-10-16 15:42:33 
     * @param url 
     * @return ResponseInfo 
     */
    public static ResponseInfo sendDelete(String url) {
        return getHttpParamReq(url,"DELETE");
    }
    
    /** 
     * @description: post请求
     * @date: 2023-10-16 17:04:07 
     * @param url 
     * @param param 
     * @return ResponseInfo 
     */
    public static ResponseInfo sendPost(String url, CommonEntityPo param){
        return getHttpBodyReq(url,param,"POST");
    }
    
    /** 
     * @description: put请求
     * @date: 2023-10-16 17:05:05 
     * @param url 
     * @param param 
     * @return ResponseInfo 
     */
    public static ResponseInfo sendPut(String url, CommonEntityPo param){
        return getHttpBodyReq(url,param,"PUT");
    }

    /**
     * 有请求体body,向指定 URL 发送方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数。
     * @return 所代表远程资源的响应结果
     */
    public static ResponseInfo getHttpBodyReq(String url, CommonEntityPo param, String requestMethodType) {
        BufferedReader in = null;
        InputStream inputStream = null;
        HttpURLConnection connection = null;
        StringBuilder result = new StringBuilder();
        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");
            //添加一些必要的请求头信息
            addHeader(connection);
            //connection.setRequestProperty("Authorization","Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJiUlR5WGJ0Q05aaS1fUkVKSGUwNHNEd2RYaTNVSHRLOWZoWndXdGdPdWdNIn0.eyJleHAiOjE2OTc0MzM5NDksImlhdCI6MTY5NzAwMTk0OSwiYXV0aF90aW1lIjoxNjk2NzYwOTcxLCJqdGkiOiJiMjcyYzM2My1kMDQ1LTRhMTAtOTc5Ni0xZGE0ZmYwNDkxYTkiLCJpc3MiOiJodHRwOi8vaWRtLWRldi5zdW53b2RhLWV2Yi5jb20vYXV0aC9yZWFsbXMvc3RhbmRhcmQiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmIxOTE4NWYtODcxZi00NTk1LWIxZTUtYTIwZTQ1MzcyZjQ3IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibnRzLWZyb250LXRlc3QiLCJub25jZSI6Ijc3MjBkM2QyLTg3NDQtNDI3Yy1iMzBhLTE5YWU2ZDM5NzY3NiIsInNlc3Npb25fc3RhdGUiOiJhNDJlNzU0ZC04MmRjLTQxNTgtOWQyYi1iZWZkNzNmMGI4NzUiLCJhY3IiOiIwIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoi6IuP5pWPIiwicHJlZmVycmVkX3VzZXJuYW1lIjoieHdkMTYiLCJnaXZlbl9uYW1lIjoi6IuP5pWPIiwibG9jYWxlIjoiemgtQ04ifQ.AUnf5meZWqYNYbfbzyqY3C9WoiL-ISCoVebvtJV-1EF8iQe2FXVEE22CLKnTvHBEoY-W62F8LtG3eW3B5LP54WBXq0JyxnMSLTjqZWMfvYmxNLfjO3rcviK9jAqqxrvLy1IR4ZVFz8ez4ThfCr3TrbammQvZgxF1jie_hx_-3RTiLTra1qyTUj8CrFRaVDBvWTt8nDu6FsRBAkqImPgZ3Jdhf-WDeVlwOkDCGPd5cUQ9KAQs2JUMY4H_jC9cgcSpQuUjNOQOnu1lnYjnsREswR7iBNSkaW6DlRry-HhD8FRs1QLOwKGcgFCBU7O9O-NCH8EyrZOriSpiPaElE2-i2Q");

            connection.setConnectTimeout(15000);
            connection.setReadTimeout(60000);
            // 发送POST请求必须设置如下两行,参数要放在http正文内
            connection.setDoOutput(true);
            connection.setDoInput(true);
            // 默认是 GET方式
            connection.setRequestMethod(requestMethodType);
            // Post 请求不使用缓存
            connection.setUseCaches(false);
            // 配置连接的Content-type,form表单是"application/x-www-form-urlencoded",json是"application/json"等
            connection.setRequestProperty("Content-Type", "application/json");
            connection.connect();
            
            //参数处理
            if(param != null){
                //打印接口入参
                logger.info("post请求接口入参:{}",JSON.toJSONString(param.getData()));
                
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
                writer.write(JSON.toJSONString(param.getData()));
                writer.close();
            }

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            
            ResponseInfo responseInfo = JSON.parseObject(result.toString(), ResponseInfo.class);
            if(responseInfo.getStatusCode() == null){
                return getFailResponse(result.toString());
            }
            return responseInfo;
        } catch (Exception e) {
            logger.error("调用MES4.0接口异常",e);
            return getExceptionResponse(e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if(inputStream != null){
                    inputStream.close();
                }
                if (connection != null) {
                    //关闭连接
                    connection.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    /*public static void main(String[] args) throws IOException {
        //=========================================邮箱==================================================
        List> files = new ArrayList<>();
        Map map = new HashMap();
        File file = new File("C:\\Users\\86188\\Desktop\\t1.png");
        map.put("name", "t1.png");
        map.put("file", file);
        files.add(map);

        Map param = new HashMap();
        param.put("data", "data");
        sendFileUrl("http://127.0.0.1:8080/sendReport", files, param);
    }*/
    
    /** 
     * @description: 有附件和参数的发送方法的请求(调用方式参考实例如上方法)
     * @date: 2023-10-23 10:41:40 
     * @param actionUrl :请求链接url
     * @param files : 附件
     * @param param :请求参数
     * @return ResponseInfo 
     */
    public static void sendFileUrl(String actionUrl, List> files, Map param){
        HttpURLConnection conn = null;
        DataOutputStream outStream = null;
        try {
            final String NEWLINE = "\r\n";
            String BOUNDARY = java.util.UUID.randomUUID().toString();
            String PREFIX = "--", LINEND = "\r\n";
            String MULTIPART_FROM_DATA = "multipart/form-data";
            String CHARSET = "UTF-8";
            URL uri = new URL(actionUrl);
            conn = (HttpURLConnection) uri.openConnection();
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(60000);
            conn.setDoInput(true);// 允许输入
            conn.setDoOutput(true);// 允许输出
            conn.setUseCaches(false);
            conn.setRequestMethod("POST"); // Post方式
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("Charsert", "UTF-8");
            conn.setRequestProperty("Accept", "application/json;charset=UTF-8");
            conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA
                    + ";boundary=" + BOUNDARY);

            outStream = new DataOutputStream(
                    conn.getOutputStream());


            // 获取表单中上传控件之外的控件数据,写入到输出流对象(根据上面分析的抓包的内容格式拼凑字符串);
            if (param != null && !param.isEmpty()) { // 这时请求中的普通参数,键值对类型的,相当于上面分析的请求中的username,可能有多个
                for (Map.Entry entry : param.entrySet()) {
                    String key = entry.getKey(); // 键,相当于上面分析的请求中的username
                    Object value = param.get(key); // 值,相当于上面分析的请求中的sdafdsa
                    outStream.writeBytes(PREFIX + BOUNDARY + NEWLINE); // 像请求体中写分割线,就是前缀+分界线+换行
                    outStream.writeBytes("Content-Disposition: form-data; "
                            + "name=\"" + key + "\"" + NEWLINE); // 拼接参数名,格式就是Content-Disposition: form-data; name="key" 其中key就是当前循环的键值对的键,别忘了最后的换行
                    outStream.writeBytes(NEWLINE); // 空行,一定不能少,键和值之间有一个固定的空行
                    outStream.write(value.toString().getBytes("UTF-8")); // 将值写入,用字节流防止乱码
                    // 或者写成:dos.write(value.toString().getBytes(charset));
                    outStream.writeBytes(NEWLINE); // 换行
                }
            }

            // 发送文件数据
            if (files != null)
                for (Map file : files) {
                    StringBuilder sb1 = new StringBuilder();
                    sb1.append(PREFIX);
                    sb1.append(BOUNDARY);
                    sb1.append(LINEND);
                    sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\""
                            + file.get("name") + "\"" + LINEND);
                    sb1.append("Content-Type: application/octet-stream; charset="
                            + CHARSET + LINEND);
                    sb1.append(LINEND);
                    outStream.write(sb1.toString().getBytes("utf-8"));    //getBytes()不加utf-8 传输中文名附件时,接收附件的地方解析文件名会乱码

                    InputStream is = new FileInputStream((File) file.get("file"));
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = is.read(buffer)) != -1) {
                        outStream.write(buffer, 0, len);
                    }

                    is.close();
                    outStream.write(LINEND.getBytes());
                }

            // 请求结束标志
            byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
            outStream.write(end_data);
            outStream.flush();

            // 得到响应码
            int res = conn.getResponseCode();
            //if (res == 200) {
                InputStream in = conn.getInputStream();
                InputStreamReader isReader = new InputStreamReader(in,"UTF-8");
                BufferedReader bufReader = new BufferedReader(isReader);
                String line = "";
                String data = "";
                while ((line = bufReader.readLine()) != null) {
                    data += line;
                }
                logger.info("读取后最后结果:" + data);
            //}
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭流
                if(outStream != null){
                    outStream.close();
                }
                //关闭连接
                if(conn != null){
                    conn.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    //multipartFile格式文件发送
    public static void sendMultipartFileUrl(String actionUrl, MultipartFile file, Map param){
        HttpURLConnection conn = null;
        DataOutputStream outStream = null;
        try {
            final String NEWLINE = "\r\n";
            String BOUNDARY = java.util.UUID.randomUUID().toString();
            String PREFIX = "--", LINEND = "\r\n";
            String MULTIPART_FROM_DATA = "multipart/form-data";
            String CHARSET = "UTF-8";
            URL uri = new URL(actionUrl);
            conn = (HttpURLConnection) uri.openConnection();
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(60000);
            conn.setDoInput(true);// 允许输入
            conn.setDoOutput(true);// 允许输出
            conn.setUseCaches(false);
            conn.setRequestMethod("POST"); // Post方式
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("Charsert", "UTF-8");
            conn.setRequestProperty("Accept", "application/json;charset=UTF-8");
            conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA
                    + ";boundary=" + BOUNDARY);

            outStream = new DataOutputStream(
                    conn.getOutputStream());


            // 获取表单中上传控件之外的控件数据,写入到输出流对象(根据上面分析的抓包的内容格式拼凑字符串);
            if (param != null && !param.isEmpty()) { // 这时请求中的普通参数,键值对类型的,相当于上面分析的请求中的username,可能有多个
                for (Map.Entry entry : param.entrySet()) {
                    String key = entry.getKey(); // 键,相当于上面分析的请求中的username
                    Object value = param.get(key); // 值,相当于上面分析的请求中的sdafdsa
                    outStream.writeBytes(PREFIX + BOUNDARY + NEWLINE); // 像请求体中写分割线,就是前缀+分界线+换行
                    outStream.writeBytes("Content-Disposition: form-data; "
                            + "name=\"" + key + "\"" + NEWLINE); // 拼接参数名,格式就是Content-Disposition: form-data; name="key" 其中key就是当前循环的键值对的键,别忘了最后的换行
                    outStream.writeBytes(NEWLINE); // 空行,一定不能少,键和值之间有一个固定的空行
                    outStream.write(value.toString().getBytes("UTF-8")); // 将值写入,用字节流防止乱码
                    // 或者写成:dos.write(value.toString().getBytes(charset));
                    outStream.writeBytes(NEWLINE); // 换行
                }
            }

            // 发送文件数据
            if (file != null){
                StringBuilder sb1 = new StringBuilder();
                sb1.append(PREFIX);
                sb1.append(BOUNDARY);
                sb1.append(LINEND);
                sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\""
                        + file.getOriginalFilename() + "\"" + LINEND);
                sb1.append("Content-Type: application/octet-stream; charset="
                        + CHARSET + LINEND);
                sb1.append(LINEND);
                outStream.write(sb1.toString().getBytes("utf-8"));    //getBytes()不加utf-8 传输中文名附件时,接收附件的地方解析文件名会乱码
                
                InputStream is = file.getInputStream();
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = is.read(buffer)) != -1) {
                    outStream.write(buffer, 0, len);
                }

                is.close();
                outStream.write(LINEND.getBytes());
            }

            // 请求结束标志
            byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
            outStream.write(end_data);
            outStream.flush();

            // 得到响应码
            int res = conn.getResponseCode();
            //if (res == 200) {
            InputStream in = conn.getInputStream();
            InputStreamReader isReader = new InputStreamReader(in,"UTF-8");
            BufferedReader bufReader = new BufferedReader(isReader);
            String line = "";
            String data = "";
            while ((line = bufReader.readLine()) != null) {
                data += line;
            }
            logger.info("读取后最后结果:" + data);
            //}
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭流
                if(outStream != null){
                    outStream.close();
                }
                //关闭连接
                if(conn != null){
                    conn.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    /** 
     * @description: 需要额外添加一些请求头信息
     * @date: 2023-10-11 14:42:07 
     */
    private static void addHeader(HttpURLConnection connection){
        //针对一些第三方系统加密header
    }
    
    /** 
     * @description: 返回请求异常信息
     * @date: 2023-10-15 17:43:36 
     * @param e 
     * @return ResponseInfo 
     */
    private static ResponseInfo getExceptionResponse(Exception e){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        e.printStackTrace(new PrintStream(baos));
        String failMsg = baos.toString();
        return getFailResponse(failMsg);
    }
    
    /** 
     * @description: 封装返回信息结果
     * @date: 2023-10-19 19:44:23 
     * @param failMsg 
     * @return ResponseInfo 
     */
    private static ResponseInfo getFailResponse(String failMsg){
        ResponseInfo responseInfo = new ResponseInfo();
        responseInfo.setStatusCode(400);
        responseInfo.setMessage(failMsg);
        return responseInfo;
    }
}

你可能感兴趣的:(http,网络协议,网络)