以为别人有坑实则自己挖坑之—— 使用HttpURLConnection请求分发

个人主机免费的内网穿透映射有限, 想要搭建多个项目就显不足, 于是乎就想到使用请求分发如下图

image-20211025181728730

用HttpURLConnection进行请求转发总是出现中文乱码, 网上查了很多人写的博客, 就以这两个我用过的大佬的代码为例, 记录一下我以为别人写的是坑, 其实是我在自己给自己挖坑的过程…

万恶之源使用注册字符集过滤器 CharacterEncodingFilter 一定! 一定! 一定! 一定! 要放在所有过滤器最前面.

花了一晚上的时间, 又饿又冻的一晚上, 大概也掉了十几上百根头发不等, 第二天吃过饭查了查jdk11API, 然后改改改出来, 在我以为问题莫名奇妙被我解决准备写下解决方案之时, 我发现我又出错, 百思不得其解复制两份工程文件一点一点复制粘贴找不同找到了万恶之源字符集过滤器位置没有在最前面注册!

测试了两个大佬的代码, 我自己创建了三个测试工程, 测试过程有些混乱, 测试的项目工程里有只注册 CharacterEncodingFilter (自己没坑), 和除了 CharacterEncodingFilter 还有使用Rest风格的过滤器 HiddenHttpMethodFilter 放在了最前面 (自己有坑)

艰难的踩坑过程

**失败一: **首先我用的是这份代码, 这份代码也有坑, 再加上我自己挖的坑, 坑中有坑: https://blog.csdn.net/lamb7758/article/details/77965461

按照上面大佬的博客, 我非常开心的把项目搭建

// 测试类中
public static void main(String[] args) {
    //发送 POST 请求
    String sr=HttpRequest.sendPost("http://192.168.8.187:8082", "text=我要发送中文!");
    System.out.println(sr);
    JSONObject json = JSONObject.fromObject(sr);
    System.out.println(json.get("data"));
}

接收请求服务器使用使用框架SpringMVC, 匹配任意路径 /*, 任意方法(默认不写)

// 接收请求服务器
@ResponseBody
@RequestMapping(value = "/*")
public AjaxResult getForward(HttpServletRequest request, HttpServletResponse response){
    Map<String, String[]> parameterMap = request.getParameterMap();
    Set<String> strings = parameterMap.keySet();
    String param = "";
    for (String string : strings) {
    param += string + ":" + Arrays.toString(parameterMap.get(string)) + "  ";
    }
    System.out.println(param);
    return new AjaxResult(200, "ok", "这是友好回复");
}

准备就绪, 开始测试!

运行发起请求 – 结果如下:

接收端收到请求:

image-20211025160526513

发送端收到回复:

image-20211025160612396

臻完美, 好开心! 好快乐! 接下来就将做成web项目, 实际体验一把在前端发送请求, 让请求服务器进行转发:

这里为了测试方便, 我把转发的URL和参数都写死, 实际中应该根据收到的请求来确定转发的路径和参数, 转发服务器采用SpringMVC框架, 匹配任意路径, 任意方法:

// 转发服务器
@ResponseBody
@RequestMapping(value = "/*")
public String getForward(HttpServletRequest request, HttpServletResponse response){
    String res = HttpRequest.sendPost("http://192.168.8.187:8082", "text=我要发送中文!");
    return res;
}

接收端服务器不做更改还是原来的配置

// 接收请求服务器
@ResponseBody
@RequestMapping(value = "/*")
public AjaxResult getForward(HttpServletRequest request, HttpServletResponse response){
    Map<String, String[]> parameterMap = request.getParameterMap();
    Set<String> strings = parameterMap.keySet();
    String param = "";
    for (String string : strings) {
    param += string + ":" + Arrays.toString(parameterMap.get(string)) + "  ";
    }
    System.out.println(param);
    return new AjaxResult(200, "ok", "这是友好回复");
}

tomcat配置地址:http://localhost:8081, 准备就绪, 启动web项目,

image-20211025161915336

浏览器里随便发起一个到转发服务器的请求:

image-20211025162300081

经过转发服务器, 再次向接收请求的服务器发送一个POST请求, 参数是:text=我要发送中文!

image-20211025162409458

现在来看接收端服务器都收到了啥:

image-20211025162539205

想吐血, 一样的代码, 测试挺好, 做成web项目放tomcat里运行就这样? 一脸懵逼

大佬的代码看不懂也不会改, 接着网上查"HttpURLConnection 请求中文乱码"

大佬代码出现乱码解决方案:

这个问题是第二天找的, JDK11文档中写道

image-20211025184435917

最后我做了这样的修改, 还有解决我自己字符集过滤器注册要放第一位的问题就可以正常传输参数没有乱码了:

// // 获取URLConnection对象对应的输出流
// out = new PrintWriter(conn.getOutputStream());
// 以上代码更改为:
OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
out = new PrintWriter(osw);
下面这位大佬的代码没问题, 推荐使用

但在以上问题解决之前, 我是又查了很多资料, 测试了第二份代码, 代码没问题, 是我自己有坑, 把字符集过滤器配置最顶上就没问题

于是乎我又找到了另外一个大佬的代码, 写的可齐全, 还能转发文件

https://www.cnblogs.com/liuxm2017/p/10874757.html

测试这份代码可谓艰辛, 之前一直用注册有 HiddenHttpMethodFilter 过滤器, 并且放在最前面的项目工程一直测试都是乱码, 然后一直以为都是代码的坑, 放一边不管, 又研究第一个代码, 终于找出第一个代码的问题所在, 才发现我自己有坑, 再来用这份代码就没有问题了.

下面演示请求转发仅需简单更改前端的配置使用

最后放一个我自己随便写的转发代码, 只是简单的POST, GET带参转发, 使用过程前端只要带上参数forwardUrl=指定转发的服务器 (例如)

正常的前端请求:

image-20211025202036956

使用请求转发进行如下修改: 1.更改url 2.添加请求参数fowrdUrl

image-20211025192027370

请求转发服务器:

@ResponseBody
@RequestMapping(value = "/*")
public String getForward(HttpServletRequest request, HttpServletResponse response){
    // 通过forwardUrl参数和requestURL,替换为最终要请求的URL
    String forwardUrl = request.getParameter("forwardUrl");
    String requestURL = request.getRequestURL().toString();
    if(!"".equals(requestURL) && forwardUrl!=null && !"".equals(forwardUrl)){
        Integer index = 0;
        for(int i=0; i<3; i++){
            int temp = requestURL.indexOf("/", index);
            index = temp + 1;
            if(temp == -1)
                index = requestURL.length()+1;
        }
        forwardUrl = requestURL.replace(requestURL.substring(0, index - 1), forwardUrl);
        // 取出所有参数封装到一个新的Map集合待发起新请求
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, String> forwardParams = new HashMap<>();
        Set<String> paramkeySet = parameterMap.keySet();
        for (String paramKey : paramkeySet) {
            if(!"forwardUrl".equals(paramKey)){
                String[] params = parameterMap.get(paramKey);
                for (String param : params) {
                    forwardParams.put(paramKey, param);
                }
            }else{
                String[] params = parameterMap.get(paramKey);
                for (String param : params) {

                }
            }
        }
        // 转发请求并获取结果返回
        String method = request.getMethod();
        String res = null;
        if("POST".equals(method)){
            res = ForwardHttpConnection.postForm(forwardUrl, null ,forwardParams);
        }else if("GET".equals(method)){
            res = ForwardHttpConnection.get(forwardUrl, null, forwardParams);
        }
        return res;
    }
    return "请确认请求中是否带上forwardUrl参数";
}

发起一个添加数据请求

带参请求

目标后台服务器接收到正确参数

没有乱码

添加数据结果显示

okkkk

至此个人使用简单的GET, POST请求转发配置完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值