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.

309 lines
12 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 com.alibaba.fastjson.JSONObject;
import com.dsideal.gw.Const.RetBean;
import com.dsideal.gw.GwApplication;
import com.dsideal.gw.Util.CommonUtil;
import com.dsideal.gw.Util.JwtUtil;
import com.jfinal.handler.Handler;
import com.jfinal.kit.StrKit;
import com.jfinal.upload.MultipartRequest;
import com.jfinal.upload.UploadFile;
import io.jsonwebtoken.Claims;
import okhttp3.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
/**
* 测试用例:
* GET
* http://10.10.21.20:8000/dsBase/dm/getDmSchoolProperty
* http://10.10.21.20:8000/dsBase/global/getGlobalList?page=1&limit=10
* POST
* http://10.10.21.20:8000/dsBase/global/testPost?a=100
* 上传文件
* http://10.10.21.20:8000/dsBase/global/testUpload
* form-data
* upfile --->参数值:选择一个文件 类型file
*/
public class RouterHandler extends Handler {
//OkHttp的实例单例模式
private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient();
/**
* 功能输出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 {
RetBean ret;
if (jo.getBoolean("success")) {
ret = new RetBean(RetBean.SUCCESS, "成功", jo);
} else {
ret = new RetBean(RetBean.ERROR, "失败", jo);
}
res.getWriter().println(ret.toJsonString());
res.getWriter().flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//OkHttp的回调函数同步执行
private void executeRequest(Request request, HttpServletResponse res) throws IOException {
Response response = OK_HTTP_CLIENT.newCall(request).execute();
if (response.isSuccessful()) {
String responseBody = null;
if (response.body() != null) {
responseBody = response.body().string();
}
JSONObject jo = JSONObject.parseObject(responseBody);
if (jo != null) {
jo.put("success", true);
}
if (jo != null) {
jo.put("http_code", response.code());
}
renderJson(res, jo);
} else {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "请求失败!");
jo.put("http_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)) {
//是不是通过了登录检查?
boolean canPass = true;
//1、存在Cookie,检查是不是正确的Cookie
Cookie[] cookies = req.getCookies();
String identity_id = null;
String person_id = null;
String bureau_id = null;
String token = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("identity_id".equals(cookie.getName())) {
String cookieValue = cookie.getValue();
identity_id = cookieValue;
}
if ("person_id".equals(cookie.getName())) {
person_id = cookie.getValue();
}
if ("bureau_id".equals(cookie.getName())) {
bureau_id = cookie.getValue();
}
if ("token".equals(cookie.getName())) {
token = cookie.getValue();
}
}
}
//如果没有找到Cookie那么直接不通过
if (StrKit.isBlank(token) || StrKit.isBlank(bureau_id) || StrKit.isBlank(identity_id) || StrKit.isBlank(person_id)) {
canPass = false;
}
//找到了Cookie,那是不是合法的Cookie呢需要检查一下Token
if (canPass) {
Map<String, Object> loginMap = new HashMap<>();
loginMap.put("identity_id", identity_id);
loginMap.put("person_id", person_id);
loginMap.put("bureau_id", bureau_id);
String cookie_token = CommonUtil.Sign(loginMap, GwApplication.PropKit.get("CookieMd5SingPwd"));
if (!token.equals(cookie_token)) {//根据Cookie中的Token和计算出来的Token是否一致
canPass = false;
}
}
if (!canPass) {
//如果不存在Cookie,那么检查是不是存在JWT,并且JWT是不是正确的
if (req.getHeader("Authorization") != null) {
String jwtToken = req.getHeader("Authorization");
Claims claims = JwtUtil.getClaims(jwtToken);
if (claims == null) {
canPass = true;
}
}
}
if (!canPass) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "登录已过期,请重新登录!");
renderJson(res, jo);
isHandled[0] = true; //停止filter
return;
}
}
//路由到哪个微服务
int xie1 = servletPath.indexOf('/'); // 找到第一个 '/' 的索引
int xie2 = servletPath.indexOf('/', xie1 + 1); // 从第一个 '/' 之后开始找第二个 '/' 的索引
//action名称
String action = servletPath.substring(xie2 + 1);
if (xie1 == -1 || xie2 == -1) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "输入的字符串格式不正确,没有找到两个 '/'。");
renderJson(res, jo);
isHandled[0] = true; //停止filter
return;
}
String prefix = servletPath.substring(xie1 + 1, xie2); // 截取两个 '/' 之间的内容
if (!GwApplication.routeList.containsKey(prefix)) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", prefix + "前缀没有找到合适的路由表,请检查是否请求正确!");
renderJson(res, jo);
isHandled[0] = true; //停止filter
return;
}
//路由到哪个微服务
String FORWARD_URL = GwApplication.routeList.get(prefix) + "/" + prefix + "/" + action;
//1、如果是上传文件
if (req.getMethod().equals("POST") && req.getContentType() != null && req.getContentType().startsWith("multipart/form-data")) {
// 指定文件类型
MediaType mediaType = MediaType.parse("multipart/form-data");
MultipartRequest mp = new MultipartRequest(req);
List<UploadFile> files = mp.getFiles();
if (files.isEmpty()) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "没有上传文件!");
renderJson(res, jo);
isHandled[0] = true;//停止filter
return;
}
UploadFile uploadFile = files.getFirst();
// 获取文件流
RequestBody requestBody = RequestBody.create(uploadFile.getFile(), mediaType);
// 构建MultipartBody
MultipartBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", uploadFile.getFileName(), requestBody)
.build();
// 构建Request
Request request = new Request.Builder()
.url(FORWARD_URL)
.post(body)
.build();
try {
executeRequest(request, res);
isHandled[0] = true;//停止filter
return;
} catch (Exception e) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "请求失败!" + e);
renderJson(res, jo);
isHandled[0] = true;//停止filter
return;
}
}
//2、处理GET请求
if (req.getMethod().equals("GET")) {
//参数:queryString
Request.Builder builder;
if (queryString != null) {
builder = new Request.Builder().url(FORWARD_URL + "?" + queryString);
} else {
builder = new Request.Builder().url(FORWARD_URL);
}
if (!StrKit.isBlank(req.getHeader("Authorization"))) {
builder.addHeader("Authorization", req.getHeader("Authorization"));
builder.addHeader("Accept", "application/json;odata=verbose");
}
Request request = builder.build();
try {
executeRequest(request, res);
isHandled[0] = true;//停止filter
return;
} catch (IOException e) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "请求失败!" + e);
renderJson(res, jo);
isHandled[0] = true;//停止filter
return;
}
}
//3、处理POST请求
if (req.getMethod().equals("POST")) {
RequestBody body = createRequestBody(req);
Request request;
if (queryString != null) {
request = new Request.Builder().url(FORWARD_URL + "?" + queryString)
.addHeader("Authorization", req.getHeader("Authorization"))
.addHeader("Accept", "application/json;odata=verbose")
.post(body).build();
} else {
request = new Request.Builder().url(FORWARD_URL)
.addHeader("Authorization", req.getHeader("Authorization"))
.addHeader("Accept", "application/json;odata=verbose")
.post(body).build();
}
try {
executeRequest(request, res);
isHandled[0] = true;//停止filter
return;
} catch (IOException e) {
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "请求失败!" + e);
renderJson(res, jo);
isHandled[0] = true;//停止filter
return;
}
}
//4、其它的OPTIONS
JSONObject jo = new JSONObject();
jo.put("success", false);
jo.put("message", "系统只支持GET,POST其它的OPTIONS不支持文件上传请使用S3协议进行直传不通过JAVA处理JAVA只处理授权");
renderJson(res, jo);
//停止filter
isHandled[0] = true;
}
}