mirror of
https://github.com/continew-org/continew-starter.git
synced 2026-01-12 06:57:11 +08:00
feat(core): ServletUtils 新增 isMultipart、isForm、isStream 方法
This commit is contained in:
@@ -18,6 +18,7 @@ package top.continew.starter.core.util;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
@@ -189,5 +190,38 @@ public class ServletUtils extends JakartaServletUtil {
|
||||
write(response, data, MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查请求是否为 {@code multipart/form-data} 格式(常用于文件上传)
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return true: 是; false: 否
|
||||
* @since 2.15.1
|
||||
*/
|
||||
public static boolean isMultipart(HttpServletRequest request) {
|
||||
return StrUtil.startWithIgnoreCase(request.getContentType(), "multipart/");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 HTTP 请求是否为 {@code application/x-www-form-urlencoded} 格式(标准表单提交)
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return true: 是; false: 否
|
||||
* @see MediaType#APPLICATION_FORM_URLENCODED_VALUE
|
||||
* @since 2.15.1
|
||||
*/
|
||||
public static boolean isForm(HttpServletRequest request) {
|
||||
return StrUtil.contains(request.getContentType(), MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 HTTP 响应是否为 {@code Server-Sent Events (SSE)} 流格式
|
||||
*
|
||||
* @param response 响应对象
|
||||
* @return true: 是; false: 否
|
||||
* @see MediaType#TEXT_EVENT_STREAM_VALUE
|
||||
* @since 2.15.1
|
||||
*/
|
||||
public static boolean isStream(HttpServletResponse response) {
|
||||
return StrUtil.contains(response.getContentType(), MediaType.TEXT_EVENT_STREAM_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,12 @@ package top.continew.starter.core.wrapper;
|
||||
|
||||
import jakarta.servlet.ReadListener;
|
||||
import jakarta.servlet.ServletInputStream;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.util.ServletUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
@@ -77,8 +76,8 @@ public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {
|
||||
? new FastByteArrayOutputStream(contentLength)
|
||||
: new FastByteArrayOutputStream();
|
||||
// 判断是否为文件上传请求
|
||||
if (!isMultipartContent(request)) {
|
||||
if (isFormRequest()) {
|
||||
if (!ServletUtils.isMultipart(request)) {
|
||||
if (ServletUtils.isForm(request)) {
|
||||
writeRequestParametersToCachedContent();
|
||||
} else {
|
||||
StreamUtils.copy(request.getInputStream(), cachedContent);
|
||||
@@ -90,7 +89,7 @@ public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
// 如果是文件上传,直接返回原始输入流
|
||||
if (isMultipartContent(super.getRequest())) {
|
||||
if (ServletUtils.isMultipart((HttpServletRequest)super.getRequest())) {
|
||||
return super.getRequest().getInputStream();
|
||||
}
|
||||
synchronized (this) {
|
||||
@@ -102,7 +101,7 @@ public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {
|
||||
@Override
|
||||
public BufferedReader getReader() throws IOException {
|
||||
// 如果是文件上传,直接返回原始Reader
|
||||
if (isMultipartContent(super.getRequest())) {
|
||||
if (ServletUtils.isMultipart((HttpServletRequest)super.getRequest())) {
|
||||
return super.getRequest().getReader();
|
||||
}
|
||||
|
||||
@@ -153,22 +152,6 @@ public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {
|
||||
return cachedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前请求是否为 multipart/form-data 类型的文件上传请求。 该类型一般用于表单上传文件的场景,例如 enctype="multipart/form-data"。
|
||||
*
|
||||
* @param request 当前 HTTP 请求对象
|
||||
* @return true 表示为 multipart 文件上传请求;否则为 false
|
||||
*/
|
||||
public boolean isMultipartContent(ServletRequest request) {
|
||||
String contentType = request.getContentType();
|
||||
return contentType != null && contentType.toLowerCase().startsWith("multipart/");
|
||||
}
|
||||
|
||||
private boolean isFormRequest() {
|
||||
String contentType = getContentType();
|
||||
return (contentType != null && contentType.contains(MediaType.APPLICATION_FORM_URLENCODED_VALUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Body 缓存的ServletInputStream实现 DefaultServerRequestBuilder.BodyInputStream
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@ import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.WriteListener;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponseWrapper;
|
||||
import org.springframework.http.MediaType;
|
||||
import top.continew.starter.core.util.ServletUtils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -46,30 +46,11 @@ public class RepeatReadResponseWrapper extends HttpServletResponseWrapper {
|
||||
|
||||
public RepeatReadResponseWrapper(HttpServletResponse response) {
|
||||
super(response);
|
||||
checkStreamingResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String type) {
|
||||
super.setContentType(type);
|
||||
// 根据 Content-Type 判断是否为流式响应
|
||||
if (type != null) {
|
||||
String lowerType = type.toLowerCase();
|
||||
isStreamingResponse = lowerType.contains(MediaType.TEXT_EVENT_STREAM_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkStreamingResponse() {
|
||||
String contentType = getContentType();
|
||||
if (contentType != null) {
|
||||
String lowerType = contentType.toLowerCase();
|
||||
isStreamingResponse = lowerType.contains(MediaType.TEXT_EVENT_STREAM_VALUE);
|
||||
}
|
||||
isStreamingResponse = ServletUtils.isStream(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletOutputStream getOutputStream() throws IOException {
|
||||
checkStreamingResponse();
|
||||
// 对于 SSE 流式响应,直接返回原始响应流,不做额外处理
|
||||
if (isStreamingResponse) {
|
||||
return super.getOutputStream();
|
||||
@@ -103,7 +84,6 @@ public class RepeatReadResponseWrapper extends HttpServletResponseWrapper {
|
||||
|
||||
@Override
|
||||
public PrintWriter getWriter() throws IOException {
|
||||
checkStreamingResponse();
|
||||
if (isStreamingResponse) {
|
||||
// 对于 SSE 流式响应,直接返回原始响应写入器,不做额外处理
|
||||
return super.getWriter();
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
package top.continew.starter.log.http.servlet;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.util.ServletUtils;
|
||||
import top.continew.starter.core.wrapper.RepeatReadRequestWrapper;
|
||||
import top.continew.starter.log.http.RecordableHttpRequest;
|
||||
|
||||
@@ -75,7 +75,7 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest
|
||||
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
return JakartaServletUtil.getHeaderMap(request);
|
||||
return ServletUtils.getHeaderMap(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,7 +83,7 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest
|
||||
try {
|
||||
RepeatReadRequestWrapper wrappedRequest = WebUtils
|
||||
.getNativeRequest(request, RepeatReadRequestWrapper.class);
|
||||
if (wrappedRequest == null || wrappedRequest.isMultipartContent(request)) {
|
||||
if (wrappedRequest == null || ServletUtils.isMultipart(request)) {
|
||||
return null;
|
||||
}
|
||||
String body = wrappedRequest.getContentAsString();
|
||||
@@ -96,12 +96,12 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest
|
||||
@Override
|
||||
public String getParams() {
|
||||
String body = this.getBody();
|
||||
return CharSequenceUtil.isNotBlank(body) ? body : JSONUtil.toJsonStr(JakartaServletUtil.getParamMap(request));
|
||||
return CharSequenceUtil.isNotBlank(body) ? body : JSONUtil.toJsonStr(ServletUtils.getParamMap(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIp() {
|
||||
return JakartaServletUtil.getClientIP(request);
|
||||
return ServletUtils.getClientIP(request);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user