You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
7.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.dsideal.gw.Handler;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.dsideal.gw.GwApplication;
import com.jfinal.handler.Handler;
import okhttp3.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
public class RouterHandler extends Handler {
/**
* 功能输出JSON文本串
*
* @param res
* @param jo
*/
public void renderJson(HttpServletResponse res, JSONObject jo) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Cache-Control", "no-cache");
res.setCharacterEncoding("UTF-8");
res.setContentType("application/json");
try {
res.getWriter().println(jo);
res.getWriter().flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 测试用例:
* GET
* http://10.10.21.20:8000/ds-base/dm/getDmSchoolProperty
* http://10.10.21.20:8000/ds-base/global/getGlobalList?page=1&limit=10
* <p>
* POST
* http://10.10.21.20:8000/ds-base/global/testPost?a=100
*/
//OkHttp的实例单例模式
private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient();
//OkHttp的回调函数同步执行
private void executeRequest(Request request, HttpServletResponse res) throws IOException {
Response response = OK_HTTP_CLIENT.newCall(request).execute();
if (response.isSuccessful()) {
String responseBody = response.body().string();
JSONObject jo = JSONUtil.parseObj(responseBody).put("success", true).put("code", response.code());
renderJson(res, jo);
} else {
JSONObject jo = new JSONObject();
jo.put("message", "请求失败!");
jo.put("code", response.code());
renderJson(res, jo);
}
}
public static RequestBody createRequestBody(HttpServletRequest req) {
FormBody.Builder formBodyBuilder = new FormBody.Builder();
// 遍历请求中的参数
Enumeration<String> parameterNames = req.getParameterNames();
while (parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
String paramValue = req.getParameter(paramName);
formBodyBuilder.add(paramName, paramValue);
}
// 构建RequestBody
return formBodyBuilder.build();
}
@Override
public void handle(String target, HttpServletRequest req, HttpServletResponse res, boolean[] isHandled) {
//可以正确获取到URL的完整路径
String servletPath = req.getServletPath();
String queryString = req.getQueryString();
//对于根目录的访问,放行
if (servletPath.equals("/")) {
next.handle(target, req, res, isHandled);
return;
}
//如果是白名单不检查jwt,否则需要检查jwt
if (GwApplication.whiteSet.contains(servletPath)) {
System.out.println("白名单内链接不检查jwt!");
} else {
System.out.println("不包含在白名单内链接检查jwt!");
}
//路由到哪个微服务
int firstSlashIndex = servletPath.indexOf('/'); // 找到第一个 '/' 的索引
int secondSlashIndex = servletPath.indexOf('/', firstSlashIndex + 1); // 从第一个 '/' 之后开始找第二个 '/' 的索引
//action名称
String action = servletPath.substring(secondSlashIndex + 1);
if (firstSlashIndex != -1 && secondSlashIndex != -1) {
String prefix = servletPath.substring(firstSlashIndex + 1, secondSlashIndex); // 截取两个 '/' 之间的内容
if (!GwApplication.routeList.containsKey(prefix)) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", prefix + "前缀没有找到合适的路由表,请检查是否请求正确!");
renderJson(res, jo);
} else {
//路由到哪个微服务
String FORWARD_URL = GwApplication.routeList.get(prefix) + "/" + action;
//处理GET请求
if (req.getMethod().equals("GET")) {
//参数:queryString
Request request;
if (queryString != null) {
request = new Request.Builder().url(FORWARD_URL + "?" + queryString).get().build();
} else {
request = new Request.Builder().url(FORWARD_URL).get().build();
}
try {
executeRequest(request, res);
} catch (IOException e) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "请求失败!" + e);
renderJson(res, jo);
}
}//处理POST请求
else if (req.getMethod().equals("POST")) {
RequestBody body = createRequestBody(req);
Request request;
if (queryString != null) {
request = new Request.Builder().url(FORWARD_URL + "?" + queryString).post(body).build();
} else {
request = new Request.Builder().url(FORWARD_URL).post(body).build();
}
try {
executeRequest(request, res);
} catch (IOException e) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "请求失败!" + e);
renderJson(res, jo);
}
} else //上传文件
//TODO
if (req.getContentType().startsWith("multipart/form-data")) {
// 指定文件类型
MediaType mediaType = MediaType.parse("multipart/form-data");
// 创建RequestBody
File file = new File("/path/to/your/file.jpg");
RequestBody requestBody = RequestBody.create(mediaType, file);
// 构建MultipartBody
MultipartBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(), requestBody)
.build();
// 构建Request
Request request = new Request.Builder()
.url("http://your.upload.url/post")
.post(body)
.build();
} else {
// MinIO - 服务端签名直传(前端 + 后端 + 效果演示)
//https://blog.csdn.net/CYK_byte/article/details/140254412
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "系统只支持GET,POST其它的OPTIONS不支持文件上传请使用S3协议进行直传不通过JAVA处理JAVA只处理授权");
renderJson(res, jo);
}
}
} else {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "输入的字符串格式不正确,没有找到两个 '/'。");
renderJson(res, jo);
}
//停止filter
isHandled[0] = true;
}
}