parent
c8df5be72e
commit
2f5c6a82ed
18 changed files with 272 additions and 28 deletions
@ -0,0 +1,19 @@ |
|||||||
|
package com.teaching.backend.config; |
||||||
|
|
||||||
|
import com.teaching.backend.filter.ValidationInterceptor; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
public class WebConfig implements WebMvcConfigurer { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private ValidationInterceptor validationInterceptor; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addInterceptors(InterceptorRegistry registry) { |
||||||
|
registry.addInterceptor(validationInterceptor).addPathPatterns("/**"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
package com.teaching.backend.filter; |
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils; |
||||||
|
|
||||||
|
import javax.servlet.ReadListener; |
||||||
|
import javax.servlet.ServletInputStream; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletRequestWrapper; |
||||||
|
import java.io.*; |
||||||
|
|
||||||
|
public class BodyReaderWrapper extends HttpServletRequestWrapper { |
||||||
|
private final byte[] requestBody; |
||||||
|
|
||||||
|
public BodyReaderWrapper(HttpServletRequest request) throws IOException { |
||||||
|
super(request); |
||||||
|
try (InputStream inputStream = request.getInputStream()) { |
||||||
|
requestBody = IOUtils.toByteArray(inputStream); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ServletInputStream getInputStream() { |
||||||
|
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody); |
||||||
|
return new ServletInputStream() { |
||||||
|
@Override |
||||||
|
public boolean isFinished() { |
||||||
|
return byteArrayInputStream.available() == 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isReady() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setReadListener(ReadListener readListener) { |
||||||
|
// no-op
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int read() throws IOException { |
||||||
|
return byteArrayInputStream.read(); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BufferedReader getReader() throws IOException { |
||||||
|
return new BufferedReader(new InputStreamReader(getInputStream())); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.teaching.backend.filter; |
||||||
|
|
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import javax.servlet.*; |
||||||
|
import javax.servlet.annotation.WebFilter; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
@Component |
||||||
|
@WebFilter(urlPatterns = "/*") |
||||||
|
public class ReplaceStreamFilter implements Filter { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void init(FilterConfig filterConfig) { |
||||||
|
// no-op
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
||||||
|
ServletRequest requestWrapper = null; |
||||||
|
if (request instanceof HttpServletRequest) { |
||||||
|
requestWrapper = new BodyReaderWrapper((HttpServletRequest) request); |
||||||
|
} |
||||||
|
if (requestWrapper == null) { |
||||||
|
chain.doFilter(request, response); |
||||||
|
} else { |
||||||
|
chain.doFilter(requestWrapper, response); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void destroy() { |
||||||
|
// no-op
|
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,13 @@ |
|||||||
|
package com.teaching.backend.filter; |
||||||
|
|
||||||
|
import java.lang.annotation.ElementType; |
||||||
|
import java.lang.annotation.Retention; |
||||||
|
import java.lang.annotation.RetentionPolicy; |
||||||
|
import java.lang.annotation.Target; |
||||||
|
|
||||||
|
@Target(ElementType.METHOD) |
||||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||||
|
public @interface ValidateParams { |
||||||
|
String[] value(); // 要校验的参数名称
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,83 @@ |
|||||||
|
package com.teaching.backend.filter; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
import org.springframework.web.method.HandlerMethod; |
||||||
|
import org.springframework.web.servlet.HandlerInterceptor; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.IOException; |
||||||
|
import java.lang.reflect.Method; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Component |
||||||
|
public class ValidationInterceptor implements HandlerInterceptor { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private ObjectMapper objectMapper; |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
||||||
|
if (handler instanceof HandlerMethod) { |
||||||
|
HandlerMethod handlerMethod = (HandlerMethod) handler; |
||||||
|
Method method = handlerMethod.getMethod(); |
||||||
|
ValidateParams validateParams = method.getAnnotation(ValidateParams.class); |
||||||
|
|
||||||
|
if (validateParams != null) { |
||||||
|
Map<String, Object> parameterMap = new HashMap<>(); |
||||||
|
|
||||||
|
// 处理路径变量
|
||||||
|
parameterMap.putAll(getPathVariableValues(request, handlerMethod)); |
||||||
|
|
||||||
|
// 处理请求参数
|
||||||
|
parameterMap.putAll(getRequestParamValues(request)); |
||||||
|
|
||||||
|
// 处理请求体中的参数
|
||||||
|
if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) { |
||||||
|
Map<String, Object> bodyParams = objectMapper.readValue(request.getInputStream(), Map.class); |
||||||
|
parameterMap.putAll(bodyParams); |
||||||
|
} |
||||||
|
|
||||||
|
for (String paramName : validateParams.value()) { |
||||||
|
Object paramValue = parameterMap.get(paramName); |
||||||
|
|
||||||
|
if (paramValue == null || (paramValue instanceof String && ((String) paramValue).trim().isEmpty())) { |
||||||
|
handleErrorResponse(response, paramName + " 参数不能为空"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, Object> getPathVariableValues(HttpServletRequest request, HandlerMethod handlerMethod) { |
||||||
|
Map<String, Object> pathVariableValues = new HashMap<>(); |
||||||
|
Map<String, String> uriTemplateVars = (Map<String, String>) request.getAttribute("org.springframework.web.servlet.HandlerMapping.uriTemplateVariables"); |
||||||
|
if (uriTemplateVars != null) { |
||||||
|
pathVariableValues.putAll(uriTemplateVars); |
||||||
|
} |
||||||
|
return pathVariableValues; |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, Object> getRequestParamValues(HttpServletRequest request) { |
||||||
|
Map<String, Object> requestParamValues = new HashMap<>(); |
||||||
|
Map<String, String[]> paramMap = request.getParameterMap(); |
||||||
|
for (Map.Entry<String, String[]> entry : paramMap.entrySet()) { |
||||||
|
if (entry.getValue() != null && entry.getValue().length > 0) { |
||||||
|
requestParamValues.put(entry.getKey(), entry.getValue()[0]); |
||||||
|
} else { |
||||||
|
requestParamValues.put(entry.getKey(), null); |
||||||
|
} |
||||||
|
} |
||||||
|
return requestParamValues; |
||||||
|
} |
||||||
|
|
||||||
|
private void handleErrorResponse(HttpServletResponse response, String errorMessage) throws IOException { |
||||||
|
response.setStatus(HttpServletResponse.SC_BAD_REQUEST); |
||||||
|
response.setContentType("application/json;charset=UTF-8"); |
||||||
|
response.getWriter().write("{\"error\": \"" + errorMessage + "\"}"); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue