服务端:
/** * 门店网页代理. * * @param shopId 门店Id */ @RequestMapping("/proxy/{shopId}/**") public void proxyQuery(@PathVariable String shopId, @RequestBody(required = false) String requestBody, HttpServletRequest request, HttpServletResponse response) throws IOException {
//请求可能是vue发起的,或nginx中转的,所以根据request拼接可能不正确,需要配置文件指定 //http://192.168.26.135:9000/api/shop-result String callbackUrl = applicationProperties.getRpcCallbackUrl(); callbackUrl = callbackUrl.substring(0, callbackUrl.indexOf("/api/")); String baseUrl = callbackUrl + "/proxy/" + shopId + "/";
// 获取要代理的路径 //http://localhost:18080/proxy/530/xxx/cache/view/query // 去掉 /proxy/{id} 前缀,提取剩余部分 String fullPath = request.getRequestURI(); String proxyPath = fullPath.substring(fullPath.indexOf(shopId) + shopId.length()); System.out.println("proxy Path: " + proxyPath);
// 获取查询参数部分 String queryString = request.getQueryString(); if (queryString != null) { proxyPath += "?" + queryString; } System.out.println("proxyPath: " + proxyPath);
//请求头 Map<String, String> headersMap = new HashMap<>(); Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); if(headerName.toLowerCase().equals("accept-encoding")){ continue; } headersMap.put(headerName, request.getHeader(headerName)); } headersMap.put("Accept-Encoding", "identity"); //要求明文返回
//通过tcp调用,获取返回结果 String content = "....";
//http结果的JSON JSONObject json = JSONObject.fromObject(content); int responseCode = json.getInt("responseCode"); String responseMessage = json.getString("responseMessage"); Map<String, List<String>> headers = (Map<String, List<String>>)json.get("headerFields");
// 添加所有头字段 if(headers!=null) { for (Map.Entry<String, List<String>> entry : headers.entrySet()) { String headerName = entry.getKey(); // 跳过null键(状态行) if (headerName != null) { if(headerName.toLowerCase().equals("transfer-encoding")){ continue; } if(headerName.toLowerCase().equals("content-encoding")){ continue; } for (String value : entry.getValue()) { response.addHeader(headerName, value); } } } } // 设置状态码 response.setStatus(responseCode);
//内容 if(json.containsKey("webContent")) { String webContent = json.getString("webContent");
//<link rel="shortcut icon" href=static/favicon.png type=image/png> //<link href=/xxx/ //<script type=text/javascript src=/xxx //资源路径不能以斜杠开头,否则无视base了。 if (webContent.contains("<head>")) { webContent = webContent.replace("<head>", "<head><base href=\"" + baseUrl + "\">"); webContent = webContent.replace("<link href=/xxx/", "<link href=xxx/"); webContent = webContent.replace("<script type=text/javascript src=/xxx", "<script type=text/javascript src=xxx");
//<form id='item_menu_form' action="/xxx/cache/view/itemMenu" //<form id='main_form' action="/xxx/cache/view/query" webContent = webContent.replace("action=\"/xxx","action=\"xxx"); } byte[] data = webContent.getBytes("UTF-8"); response.setContentLength(data.length); response.getOutputStream().write(data); }else{ response.getOutputStream().write("error".getBytes("UTF-8")); } response.getOutputStream().close(); }
客户端,负责接收请求,执行get或post,然后返回内容到服务端。
/** * 获取网页内容. * * @param url 网址 * @return */ private Map<String, Object> getUrlContent(String url,String requestMethod,Map<String, String> headersMap,String body) {
Map<String, Object> data = new HashMap<>();
HttpURLConnection conn = null; try { conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestMethod(requestMethod); conn.setConnectTimeout(5000); // 连接超时 5秒 conn.setReadTimeout(10000); // 读取超时 10秒
//header信息 if (requestMethod.equals("POST")) { if (headersMap != null) { for (String key : headersMap.keySet()) { conn.setRequestProperty(key, headersMap.get(key)); } }
//body内容 if (body != null && body.length() > 0) { conn.setDoOutput(true); try (OutputStream out = conn.getOutputStream()) { out.write(body.getBytes("UTF-8")); } } }
// 检查 HTTP 响应码(如 200 表示成功) int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (InputStream in = conn.getInputStream()) { byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { baos.write(buffer, 0, bytesRead); } }
byte[] fullContent = baos.toByteArray(); data.put("webContent", new String(fullContent, "UTF-8"));
} data.put("headerFields", filterNullKey(conn.getHeaderFields())); data.put("responseCode", responseCode); data.put("responseMessage", conn.getResponseMessage());
} catch (Exception e) { log.error("发生错误:", e); data.put("responseCode", "500"); data.put("responseMessage", e.getMessage()); } finally { if (conn != null) { conn.disconnect(); // 确保连接关闭 } } return data; }
|