放炮罚机器人添加http协议
parent
4ea9fea6f0
commit
b96271e61c
|
|
@ -34,4 +34,13 @@ public class Config {
|
|||
/** 默认群组ID */
|
||||
public static final String DEFAULT_GROUP_ID = "426149";
|
||||
|
||||
/**
|
||||
* 机器人HTTP服务端口(接收 web_group 通过 HTTP 发送的 225 协议)
|
||||
* 规则:TCP端口 + 1000(TCP=8917,HTTP=9917)
|
||||
*/
|
||||
public static final int HTTP_SERVER_PORT = 9917;
|
||||
|
||||
/** 机器人HTTP服务路径 */
|
||||
public static final String HTTP_PATH_JOIN_ROOM = "/robot/joinRoom";
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package robot.zp;
|
|||
|
||||
import com.robot.GameController;
|
||||
import com.robot.GameInterceptor;
|
||||
import com.robot.MainServer;
|
||||
import com.taurus.core.entity.ITObject;
|
||||
import com.taurus.core.entity.TObject;
|
||||
import com.taurus.core.plugin.redis.Redis;
|
||||
|
|
@ -57,6 +58,34 @@ public class EXGameController extends GameController {
|
|||
String roomId = params.getString("roomid");
|
||||
int groupId = params.getInt("groupid");
|
||||
|
||||
ITObject result = processWebGroupJoin(robotId, roomId, groupId, params);
|
||||
|
||||
// 仅在"ID冲突"场景下回错误响应,其他场景保持原有静默行为不变
|
||||
int code = result.containsKey("code") ? result.getInt("code") : 0;
|
||||
if (code == 1) {
|
||||
ITObject errorResponse = TObject.newInstance();
|
||||
errorResponse.putString("status", "failed");
|
||||
errorResponse.putString("message", result.containsKey("message") ? result.getString("message") : "处理失败");
|
||||
MainServer.instance.sendResponse(gid, 1, errorResponse, session);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理 web_group 加入房间请求 - 核心逻辑(与传输方式无关)
|
||||
* 供 TCP 入口(webGroup)和 HTTP 入口(RobotHttpServer)共用
|
||||
*
|
||||
* @param robotId 机器人ID
|
||||
* @param roomId 房间ID
|
||||
* @param groupId 群组ID
|
||||
* @param params 原始参数
|
||||
* @return ITObject 处理结果,包含:
|
||||
* code (0=成功, 1=ID冲突需告知调用方, 2=不同机器人冲突静默忽略)
|
||||
* message (描述信息)
|
||||
*/
|
||||
public ITObject processWebGroupJoin(int robotId, String roomId, int groupId, ITObject params) {
|
||||
ITObject result = TObject.newInstance();
|
||||
//检查Redis中该房间是否真的包含当前机器人
|
||||
if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) {
|
||||
//Redis中不存在该机器人 清理本地可能的错误映射
|
||||
|
|
@ -80,7 +109,9 @@ public class EXGameController extends GameController {
|
|||
if (robotId != existingRobotId) {
|
||||
//不同机器人的冲突
|
||||
log.warn("房间{}中Redis已存在机器人{},当前机器人{}不执行加入逻辑", roomId, existingRobotId, robotId);
|
||||
return;
|
||||
result.putInt("code", 2);
|
||||
result.putString("message", "Redis已存在其他机器人,不执行加入逻辑");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -89,6 +120,9 @@ public class EXGameController extends GameController {
|
|||
//加入房间
|
||||
joinRoomCommon(robotId, roomId, groupId, params);
|
||||
log.info("225已进入房间准备成功: room:{} robot:{}", roomId, robotId);
|
||||
result.putInt("code", 0);
|
||||
result.putString("message", "success");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -187,7 +221,6 @@ public class EXGameController extends GameController {
|
|||
//发送加入房间请求到game_zp_fls
|
||||
client.send(Config.JOIN_ROOM_FLS, params, response -> {
|
||||
//成功响应后才建立映射关系
|
||||
System.out.println("能进来吗");
|
||||
robotRoomMapping.put(robotUser.getConnecId(), robotUser);
|
||||
robotConnectionManager.reconnectToGameServer(response, robotUser, client);
|
||||
});
|
||||
|
|
@ -195,7 +228,6 @@ public class EXGameController extends GameController {
|
|||
log.info("已进入房间成功: {}", robotUser.getConnecId());
|
||||
Thread.sleep(1000);
|
||||
if (client.isConnected()) {
|
||||
System.out.println("发送准备");
|
||||
client.send(Config.GAME_READY_FLS, params, response -> {
|
||||
log.info("1003:{}", response);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -22,149 +22,167 @@ import static robot.zp.EXGameController.robotRoomMapping;
|
|||
* 福禄寿机器人主服务器
|
||||
* TCP服务端接收robot_mgr的协议 同时作为客户端连接game_zp_fls处理AI逻辑
|
||||
*/
|
||||
public class EXMainServer extends MainServer{
|
||||
private static final Logger log = LoggerFactory.getLogger(EXMainServer.class);
|
||||
public class EXMainServer extends MainServer {
|
||||
private static final Logger log = LoggerFactory.getLogger(EXMainServer.class);
|
||||
|
||||
private static final RobotConnectionManager robotConnectionManager = new RobotConnectionManager();
|
||||
private static final RobotConnectionManager robotConnectionManager = new RobotConnectionManager();
|
||||
/**
|
||||
* 机器人HTTP服务(接收 web_group 通过 HTTP 发送的 225 协议,替代TCP异步方式)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
private RobotHttpServer robotHttpServer;
|
||||
|
||||
//JVM关闭钩子
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
log.info("收到JVM关闭信号,开始优雅关闭...");
|
||||
try {
|
||||
//关闭所有机器人连接
|
||||
for (Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
|
||||
RobotUser robotUser = entry.getValue();
|
||||
if (robotUser.getClient() != null && robotUser.getClient().isConnected()) {
|
||||
robotConnectionManager.disconnectFromGameServer(robotUser.getConnecId());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
//关闭线程池
|
||||
robot.zp.thread.ThreadPoolConfig.shutdown();
|
||||
// 启动机器人HTTP服务(接收 web_group 通过 HTTP 发送的 225 协议)
|
||||
// 替代原 TCP 异步多线程方式(TaurusClient+CompletableFuture),降低CPU占用
|
||||
try {
|
||||
robotHttpServer = new RobotHttpServer();
|
||||
robotHttpServer.start(Config.HTTP_SERVER_PORT);
|
||||
} catch (Exception e) {
|
||||
log.error("启动 RobotHttpServer 失败,端口:" + Config.HTTP_SERVER_PORT, e);
|
||||
}
|
||||
|
||||
log.info("优雅关闭完成");
|
||||
} catch (Exception e) {
|
||||
log.error("关闭过程中发生异常", e);
|
||||
}
|
||||
}));
|
||||
//JVM关闭钩子
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
log.info("收到JVM关闭信号,开始优雅关闭...");
|
||||
try {
|
||||
//关闭所有机器人连接
|
||||
for (Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
|
||||
RobotUser robotUser = entry.getValue();
|
||||
if (robotUser.getClient() != null && robotUser.getClient().isConnected()) {
|
||||
robotConnectionManager.disconnectFromGameServer(robotUser.getConnecId());
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 先启动独立的事件处理线程(只启动一次)
|
||||
startNetEventThread();
|
||||
//关闭线程池
|
||||
robot.zp.thread.ThreadPoolConfig.shutdown();
|
||||
|
||||
// 2. 启动资源清理定时任务
|
||||
startResourceCleanupScheduler();
|
||||
log.info("优雅关闭完成");
|
||||
} catch (Exception e) {
|
||||
log.error("关闭过程中发生异常", e);
|
||||
}
|
||||
}));
|
||||
|
||||
// 3. 启动系统监控
|
||||
//startConnectionCheckScheduler();
|
||||
//测试
|
||||
Jedis jedis2 = Redis.use("group1_db2").getJedis();
|
||||
String robotskey = "g{"+Config.DEFAULT_GROUP_ID+"}:play:"+Config.DEFAULT_PID;
|
||||
Map<String, String> maprobot = jedis2.hgetAll(robotskey);
|
||||
for(Map.Entry<String, String> entry : maprobot.entrySet()) {
|
||||
log.info("{}:{}", entry.getKey(), entry.getValue());
|
||||
//是否创建
|
||||
RobotUser robotUser = new RobotUser();
|
||||
robotUser.setRobotId(entry.getKey());
|
||||
robotUser.setPassword(Config.DEFAULT_PASSWORD);
|
||||
robotUser.setGameHost(Config.GAME_SERVER_HOST);
|
||||
robotUser.setGamePort(Config.GAME_SERVER_PORT);
|
||||
robotUser.setRobotGroupid(Config.DEFAULT_GROUP_ID);
|
||||
robotUser.setRobotPid(Config.DEFAULT_PID);
|
||||
// 1. 先启动独立的事件处理线程(只启动一次)
|
||||
startNetEventThread();
|
||||
|
||||
robotRoomMapping.put(entry.getKey(), robotUser);
|
||||
}
|
||||
// 2. 启动资源清理定时任务
|
||||
startResourceCleanupScheduler();
|
||||
|
||||
for(Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
|
||||
RobotUser robotUser = entry.getValue();
|
||||
//1、登录
|
||||
//判断是否登录
|
||||
if(!robotUser.isLogin){
|
||||
robotConnectionManager.login(robotUser);
|
||||
}
|
||||
}
|
||||
// 3. 启动系统监控
|
||||
//startConnectionCheckScheduler();
|
||||
//测试
|
||||
Jedis jedis2 = Redis.use("group1_db2").getJedis();
|
||||
String robotskey = "g{" + Config.DEFAULT_GROUP_ID + "}:play:" + Config.DEFAULT_PID;
|
||||
Map<String, String> maprobot = jedis2.hgetAll(robotskey);
|
||||
for (Map.Entry<String, String> entry : maprobot.entrySet()) {
|
||||
log.info("{}:{}", entry.getKey(), entry.getValue());
|
||||
//是否创建
|
||||
RobotUser robotUser = new RobotUser();
|
||||
robotUser.setRobotId(entry.getKey());
|
||||
robotUser.setPassword(Config.DEFAULT_PASSWORD);
|
||||
robotUser.setGameHost(Config.GAME_SERVER_HOST);
|
||||
robotUser.setGamePort(Config.GAME_SERVER_PORT);
|
||||
robotUser.setRobotGroupid(Config.DEFAULT_GROUP_ID);
|
||||
robotUser.setRobotPid(Config.DEFAULT_PID);
|
||||
|
||||
log.info("福禄寿机器人服务器已启动");
|
||||
log.info("服务器将监听端口 {} 用于接收robot_mgr管理协议", gameSetting.port);
|
||||
log.info("当前线程池配置: {}", ThreadPoolConfig.getThreadPoolStatus());
|
||||
robotRoomMapping.put(entry.getKey(), robotUser);
|
||||
}
|
||||
|
||||
jedis2.close();
|
||||
}
|
||||
for (Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
|
||||
RobotUser robotUser = entry.getValue();
|
||||
//1、登录
|
||||
//判断是否登录
|
||||
if (!robotUser.isLogin) {
|
||||
robotConnectionManager.login(robotUser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 独立的事件处理线程
|
||||
*/
|
||||
private void startNetEventThread() {
|
||||
Thread eventThread = new Thread(() -> {
|
||||
while (true) {
|
||||
NetManager.processEvents();
|
||||
try {
|
||||
Thread.sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}, "Changsha_Thread");
|
||||
log.info("福禄寿机器人服务器已启动");
|
||||
log.info("服务器将监听端口 {} 用于接收robot_mgr管理协议", gameSetting.port);
|
||||
log.info("当前线程池配置: {}", ThreadPoolConfig.getThreadPoolStatus());
|
||||
|
||||
eventThread.setDaemon(true); //设置为守护线程
|
||||
eventThread.start();
|
||||
}
|
||||
jedis2.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动资源清理定时任务
|
||||
*/
|
||||
private void startResourceCleanupScheduler() {
|
||||
Thread cleanupThread = new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
//每30秒执行一次资源清理
|
||||
Thread.sleep(30000);
|
||||
ResourceCleanupUtil.performCleanup();
|
||||
log.info("线程池状态: {}", ThreadPoolConfig.getThreadPoolStatus());
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
log.error("资源清理任务异常: {}", e.getMessage(), e);
|
||||
// 发生异常时尝试清理
|
||||
try {
|
||||
ResourceCleanupUtil.performCleanup();
|
||||
} catch (Exception cleanupEx) {
|
||||
log.error("异常清理也失败: {}", cleanupEx.getMessage(), cleanupEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "ResourceCleanupThread");
|
||||
/**
|
||||
* 独立的事件处理线程
|
||||
*/
|
||||
private void startNetEventThread() {
|
||||
Thread eventThread = new Thread(() -> {
|
||||
while (true) {
|
||||
NetManager.processEvents();
|
||||
try {
|
||||
Thread.sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}, "Changsha_Thread");
|
||||
|
||||
cleanupThread.setDaemon(true);
|
||||
cleanupThread.start();
|
||||
log.info("资源清理定时任务已启动");
|
||||
}
|
||||
eventThread.setDaemon(true); //设置为守护线程
|
||||
eventThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动资源清理定时任务
|
||||
*/
|
||||
private void startResourceCleanupScheduler() {
|
||||
Thread cleanupThread = new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
//每30秒执行一次资源清理
|
||||
Thread.sleep(30000);
|
||||
ResourceCleanupUtil.performCleanup();
|
||||
log.info("线程池状态: {}", ThreadPoolConfig.getThreadPoolStatus());
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
log.error("资源清理任务异常: {}", e.getMessage(), e);
|
||||
// 发生异常时尝试清理
|
||||
try {
|
||||
ResourceCleanupUtil.performCleanup();
|
||||
} catch (Exception cleanupEx) {
|
||||
log.error("异常清理也失败: {}", cleanupEx.getMessage(), cleanupEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "ResourceCleanupThread");
|
||||
|
||||
cleanupThread.setDaemon(true);
|
||||
cleanupThread.start();
|
||||
log.info("资源清理定时任务已启动");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Room newRoom(String roomid, Map<String, String> redis_room_map) {
|
||||
return new EXRoom(roomid, redis_room_map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Room newRoom(String roomid, Map<String, String> redis_room_map) {
|
||||
return new EXRoom(roomid, redis_room_map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player newPlayer(int i, Room room, String s) {
|
||||
return new EXPlayer(i, room, s);
|
||||
}
|
||||
@Override
|
||||
public Player newPlayer(int i, Room room, String s) {
|
||||
return new EXPlayer(i, room, s);
|
||||
}
|
||||
|
||||
|
||||
protected GameController newController() {
|
||||
return new EXGameController();
|
||||
}
|
||||
protected GameController newController() {
|
||||
return new EXGameController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
// 停止机器人HTTP服务
|
||||
if (robotHttpServer != null) {
|
||||
robotHttpServer.stop();
|
||||
robotHttpServer = null;
|
||||
}
|
||||
|
||||
log.info("福禄寿机器人服务器已停止");
|
||||
}
|
||||
log.info("放炮罚机器人服务器已停止");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
package robot.zp;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.robot.Global;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.taurus.core.entity.ITObject;
|
||||
import com.taurus.core.entity.TObject;
|
||||
import com.taurus.core.util.Logger;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
public class RobotHttpServer {
|
||||
private static final Logger log = Logger.getLogger(RobotHttpServer.class);
|
||||
|
||||
/** 工作线程数(同时处理的并发请求数) */
|
||||
private static final int WORKER_THREADS = 8;
|
||||
|
||||
/** HTTP 响应超时(用于优雅关闭,秒) */
|
||||
private static final int STOP_DELAY = 2;
|
||||
|
||||
private HttpServer server;
|
||||
private ExecutorService executor;
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* 启动 HTTP 服务
|
||||
* @param port 监听端口
|
||||
* @throws IOException 端口被占用等异常
|
||||
*/
|
||||
public void start(int port) throws IOException {
|
||||
server = HttpServer.create(new InetSocketAddress(port), 0);
|
||||
server.createContext(Config.HTTP_PATH_JOIN_ROOM, new JoinRoomHandler());
|
||||
executor = Executors.newFixedThreadPool(WORKER_THREADS);
|
||||
server.setExecutor(executor);
|
||||
server.start();
|
||||
log.info("RobotHttpServer已启动,监听端口:" + port + ",路径:" + Config.HTTP_PATH_JOIN_ROOM + ",工作线程:" + WORKER_THREADS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止 HTTP 服务
|
||||
*/
|
||||
public void stop() {
|
||||
if (server != null) {
|
||||
server.stop(STOP_DELAY);
|
||||
server = null;
|
||||
}
|
||||
if (executor != null) {
|
||||
executor.shutdown();
|
||||
try {
|
||||
if (!executor.awaitTermination(STOP_DELAY, TimeUnit.SECONDS)) {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
executor.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
executor = null;
|
||||
}
|
||||
log.info("RobotHttpServer已停止");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 /robot/joinRoom 请求的 Handler
|
||||
*/
|
||||
private class JoinRoomHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handle(HttpExchange exchange) throws IOException {
|
||||
// 仅接受 POST
|
||||
if (!"POST".equalsIgnoreCase(exchange.getRequestMethod())) {
|
||||
writeJsonResponse(exchange, 405, buildErrorResponse("Method Not Allowed", "只支持POST请求"));
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> respData = new HashMap<>();
|
||||
try {
|
||||
// 读取请求体
|
||||
String body = readRequestBody(exchange);
|
||||
log.info("HTTP 收到加入房间请求:" + body);
|
||||
|
||||
// 解析 JSON
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> data = gson.fromJson(body, Map.class);
|
||||
if (data == null) {
|
||||
writeJsonResponse(exchange, 400, buildErrorResponse("Bad Request", "请求体为空或非合法JSON"));
|
||||
return;
|
||||
}
|
||||
|
||||
Number robotIdNum = (Number) data.get("robotid");
|
||||
Object roomIdObj = data.get("roomid");
|
||||
Number groupIdNum = (Number) data.get("groupid");
|
||||
|
||||
if (robotIdNum == null || roomIdObj == null || groupIdNum == null) {
|
||||
writeJsonResponse(exchange, 400, buildErrorResponse("Bad Request", "缺少必要参数 robotid/roomid/groupid"));
|
||||
return;
|
||||
}
|
||||
|
||||
int robotId = robotIdNum.intValue();
|
||||
String roomId = String.valueOf(roomIdObj);
|
||||
int groupId = groupIdNum.intValue();
|
||||
|
||||
// 构造 ITObject 参数(与原 TCP 入参保持一致)
|
||||
ITObject params = TObject.newInstance();
|
||||
params.putInt("robotid", robotId);
|
||||
params.putString("roomid", roomId);
|
||||
params.putInt("groupid", groupId);
|
||||
|
||||
// 调用公共处理逻辑(与 TCP webGroup 方法共用)
|
||||
ITObject result = ((EXGameController) Global.gameCtr).processWebGroupJoin(robotId, roomId, groupId, params);
|
||||
|
||||
int code = result.containsKey("code") ? result.getInt("code") : 0;
|
||||
String message = result.containsKey("message") ? result.getString("message") : "success";
|
||||
respData.put("code", code);
|
||||
respData.put("message", message);
|
||||
} catch (Exception e) {
|
||||
log.error("HTTP处理加入房间请求异常", e);
|
||||
respData.put("code", 500);
|
||||
respData.put("message", "服务器内部错误: " + e.getMessage());
|
||||
}
|
||||
|
||||
writeJsonResponse(exchange, 200, respData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取请求体为字符串
|
||||
*/
|
||||
private String readRequestBody(HttpExchange exchange) throws IOException {
|
||||
InputStream in = exchange.getRequestBody();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[1024];
|
||||
int n;
|
||||
while ((n = in.read(buf)) > 0) {
|
||||
baos.write(buf, 0, n);
|
||||
}
|
||||
in.close();
|
||||
return new String(baos.toByteArray(), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入 JSON 响应
|
||||
*/
|
||||
private void writeJsonResponse(HttpExchange exchange, int httpCode, Map<String, Object> data) throws IOException {
|
||||
String json = gson.toJson(data);
|
||||
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
|
||||
exchange.getResponseHeaders().set("Content-Type", "application/json; charset=UTF-8");
|
||||
exchange.sendResponseHeaders(httpCode, bytes.length);
|
||||
OutputStream out = exchange.getResponseBody();
|
||||
out.write(bytes);
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造错误响应
|
||||
*/
|
||||
private Map<String, Object> buildErrorResponse(String error, String message) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("code", -1);
|
||||
data.put("error", error);
|
||||
data.put("message", message);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue