解决SseEmitter浏览器下中文乱码问题
解决SseEmitter浏览器下中文乱码问题
·
解决SseEmitter浏览器下中文乱码问题
中文乱码产生背景
在基于SseEmitter开发实时站内信的场景下,起初使用命令行curl 访问接口中文显示正常,但到浏览器真实场景下,中文出现乱码。
浏览器下:
原因在于后台用的SpringMVC 默认返回编码格式是ISO,前台解析是utf-8。所以我们需要重写SseEmitter的extendResponse方法,修改其ContentType即可
public class SseEmitterUTF8 extends SseEmitter {
public SseEmitterUTF8(Long timeout) {
super(timeout);
}
@Override
protected void extendResponse(ServerHttpResponse outputMessage) {
super.extendResponse(outputMessage);
HttpHeaders headers = outputMessage.getHeaders();
headers.setContentType(new MediaType(MediaType.TEXT_EVENT_STREAM, StandardCharsets.UTF_8));
}
}
使用方式:使用SseEmitterUTF8替代之前的SseEmitter即可
public SseEmitter connect(String userId) throws IOException {
// 为方便演示,假如同一个用户多终端同时在线,仅保留最后一个终端
if (onlineUserEmitters.containsKey(userId)) {
SseEmitter emitter = onlineUserEmitters.remove(userId);
try {
emitter.send("您已被顶下线...");
} catch (IOException e) {
log.info("该用户可能已下线");
} finally {
emitter.complete();
}
}
// 设置超时时间(和token有效期一致,超时后不再推送消息),0表示不过期。默认30秒,超过时间未完成会抛出异常:AsyncRequestTimeoutException
SseEmitterUTF8 sseEmitter = new SseEmitterUTF8(0L);
// 注册回调
sseEmitter.onCompletion(completionCallBack(userId));
sseEmitter.onError(errorCallBack(userId));
sseEmitter.onTimeout(timeoutCallBack(userId));
onlineUserEmitters.put(userId, sseEmitter);
// 订阅个人站内消息
RTopic topic = redissonClient.getTopic(INBOX_USER_TOPIC_PREFIX + userId);
// 仅首次订阅时需要增加监听器,否则容器内会存在多个监听器,一条消息用户会收到数次
if (topic.countListeners() == 0) {
topic.addListener(PublishDTO.class, inboxTopicUserMessageListener);
}
sseEmitter.send(String.format("%s号用户,欢迎登录!", userId));
return sseEmitter;
}
效果展示,中文已正常展示

完整源码:
https://gitee.com/hongqianli/inbox-demo
更多推荐



所有评论(0)