sxwz2.0/src/main/java/art/kexue/sxwz/interceptor/CachedBodyHttpServletRequest.java
wangzhiwei 5f5c0759ce feat(notification): 实现通知功能,支持角色层级发送和课程群发
1. 修改 SysNotification 实体,新增 senderId, senderName, targetType 字段

2. 新增 SendNotificationRequest 请求DTO

3. 扩展通知类型至6种(新增用户通知、课程通知)

4. 实现角色层级权限控制,支持多级管理员通知下级

5. 支持老师群发课程通知给学生

6. 新增批量发送接口和权限配置
2026-05-15 16:57:07 +08:00

90 lines
2.4 KiB
Java

package art.kexue.sxwz.interceptor;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import java.io.*;
/**
* 可重复读取请求体的 HttpServletRequest 包装类
*
* @author 王志维
* @since 2026-04-14
*/
public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {
private final byte[] cachedBody;
public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
// 读取并缓存请求体
this.cachedBody = readBytes(request.getInputStream());
}
@Override
public ServletInputStream getInputStream() {
return new CachedBodyServletInputStream(this.cachedBody);
}
@Override
public BufferedReader getReader() {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedBody);
return new BufferedReader(new InputStreamReader(byteArrayInputStream));
}
/**
* 获取缓存的请求体字符串
*/
public String getCachedBodyString() {
return new String(cachedBody);
}
/**
* 从输入流读取字节数组
*/
private byte[] readBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[1024];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
}
/**
* 可重复读取的 ServletInputStream
*/
private static class CachedBodyServletInputStream extends ServletInputStream {
private final ByteArrayInputStream inputStream;
public CachedBodyServletInputStream(byte[] cachedBody) {
this.inputStream = new ByteArrayInputStream(cachedBody);
}
@Override
public boolean isFinished() {
return inputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) {
throw new UnsupportedOperationException();
}
@Override
public int read() {
return inputStream.read();
}
}
}