提交 683fd20d 编写于 作者: 武汉红喜's avatar 武汉红喜

whatsmars-boot-sample-web

上级 6d702c2a
......@@ -25,6 +25,7 @@
<module>whatsmars-boot-sample-mybatis</module>
<module>whatsmars-boot-sample-beans</module>
<module>whatsmars-boot-sample-actuator</module>
<module>whatsmars-boot-sample-web</module>
</modules>
<dependencies>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>whatsmars-spring-boot-samples</artifactId>
<groupId>org.hongxi</groupId>
<version>Rocket.S8</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>whatsmars-boot-sample-web</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package org.hongxi.whatsmars.boot.sample.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Created by shenhongxi on 2020/8/16.
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package org.hongxi.whatsmars.boot.sample.web;
import org.hongxi.whatsmars.boot.sample.web.filter.FirewallFilter;
import org.hongxi.whatsmars.boot.sample.web.filter.SampleSessionFilter;
import org.hongxi.whatsmars.boot.sample.web.interceptor.SampleSessionInterceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
import static org.hongxi.whatsmars.boot.sample.web.constants.Constants.EXCLUDE_PATHS;
/**
* Created by shenhongxi on 2020/8/16.
*/
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class SampleWebAutoConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(sampleSessionInterceptor())
.excludePathPatterns(Arrays.asList(EXCLUDE_PATHS))
.order(-100);
}
@Bean
public FirewallFilter firewallFilter() {
return new FirewallFilter();
}
@Bean
public SampleSessionFilter sampleSessionFilter() {
return new SampleSessionFilter();
}
/**
* interceptor 必须声明为单例
* @return
*/
@Bean
public SampleSessionInterceptor sampleSessionInterceptor() {
return new SampleSessionInterceptor();
}
}
package org.hongxi.whatsmars.boot.sample.web.constants;
/**
* Created by shenhongxi on 2020/8/16.
*/
public class Constants {
public static final int WEB_FIREWALL_FILTER_ORDER = -100;
public static final int WEB_SESSION_FILTER_ORDER = -99;
public static final String[] EXCLUDE_PATHS = new String[]{
"/error",
"/error/**",
"/actuator/**",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**/*.png",
"/**/*.jpg",
"/**/*.jpeg",
"/**/*.gif",
"/**/fonts/*",
"/**/*.svg"
};
}
package org.hongxi.whatsmars.boot.sample.web.context;
import java.util.Objects;
/**
* Created by shenhongxi on 2020/8/16.
*/
public class SampleSessionContext {
private static final ThreadLocal<SampleSessionContext> CONTEXT =
ThreadLocal.withInitial(() -> new SampleSessionContext());
private String userId;
public static SampleSessionContext get() {
return CONTEXT.get();
}
public static void set(SampleSessionContext context) {
CONTEXT.set(context);
}
public static void remove() {
CONTEXT.remove();
}
public static String getUserId() {
SampleSessionContext context = get();
if (Objects.isNull(context)) {
return null;
}
return context.userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
package org.hongxi.whatsmars.boot.sample.web.controller;
import org.hongxi.whatsmars.boot.sample.web.model.JsonResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by shenhongxi on 2020/8/16.
*/
@RestController
@RequestMapping("/sample")
public class SampleController {
@GetMapping("/hello")
public JsonResponse<String> hello(@RequestParam String userId,
@RequestParam Integer age) {
String hello = userId + "," + age;
return JsonResponse.success(hello);
}
}
package org.hongxi.whatsmars.boot.sample.web.exception;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* Created by shenhongxi on 2020/8/16.
*/
@Data
public class BusinessException extends RuntimeException {
private int code;
private String msg;
public BusinessException(int code, String msg) {
super("code:" + code + ", msg:" + msg);
this.code = code;
this.msg = msg;
}
public BusinessException(ErrorCode errorCode) {
super("code:" + errorCode.code + ", msg:" + errorCode.msg());
this.code = errorCode.code();
this.msg = errorCode.msg();
}
@AllArgsConstructor
public enum ErrorCode {
AUTH_FAIL(403, "请登录");
private int code;
private String msg;
public int code() {
return code;
}
public String msg() {
return msg;
}
}
}
package org.hongxi.whatsmars.boot.sample.web.exception;
import lombok.extern.slf4j.Slf4j;
import org.hongxi.whatsmars.boot.sample.web.model.JsonResponse;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpServletRequest;
/**
* Created by shenhongxi on 2020/8/16.
*/
@Slf4j
@ControllerAdvice
public class DefaultExceptionHandler {
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(BusinessException.class)
@ResponseBody
public JsonResponse handleLogicException(HttpServletRequest request, BusinessException e) {
log.error("business exception handled, request:{}", request.getRequestURI(), e);
return JsonResponse.error(e.getCode(), e.getMsg());
}
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(Exception.class)
@ResponseBody
public JsonResponse handleException(HttpServletRequest request, Exception e) throws Exception {
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
throw e;
}
log.error("exception handled, request:{}", request.getRequestURI(), e);
return JsonResponse.error(500, e.getMessage());
}
}
package org.hongxi.whatsmars.boot.sample.web.filter;
import org.springframework.boot.web.servlet.filter.OrderedFilter;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static org.hongxi.whatsmars.boot.sample.web.constants.Constants.WEB_FIREWALL_FILTER_ORDER;
/**
* Created by shenhongxi on 2020/8/16.
*/
public class FirewallFilter extends OncePerRequestFilter implements OrderedFilter {
private int order = REQUEST_WRAPPER_FILTER_MAX_ORDER + WEB_FIREWALL_FILTER_ORDER;
private StrictHttpFirewall firewall;
@Override
public int getOrder() {
return order;
}
public FirewallFilter() {
this.firewall = new StrictHttpFirewall();
this.firewall.setAllowUrlEncodedSlash(true);
this.firewall.setAllowBackSlash(true);
this.firewall.setAllowUrlEncodedPercent(true);
}
/**
* 遇到非法URI请求,防火墙拦截并返回418状态码
* 非法请求如:/xx/../user/info
* @param request
* @param response
* @param filterChain
* @throws ServletException
* @throws IOException
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
try {
this.firewall.getFirewalledRequest(request);
filterChain.doFilter(request, response);
} catch (RequestRejectedException e) {
response.sendError(HttpStatus.I_AM_A_TEAPOT.value());
}
}
}
\ No newline at end of file
package org.hongxi.whatsmars.boot.sample.web.filter;
import org.hongxi.whatsmars.boot.sample.web.context.SampleSessionContext;
import org.springframework.boot.web.servlet.filter.OrderedFilter;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static org.hongxi.whatsmars.boot.sample.web.constants.Constants.WEB_SESSION_FILTER_ORDER;
/**
* Created by shenhongxi on 2020/8/16.
*/
public class SampleSessionFilter extends OncePerRequestFilter implements OrderedFilter {
private int order = REQUEST_WRAPPER_FILTER_MAX_ORDER + WEB_SESSION_FILTER_ORDER;
@Override
public int getOrder() {
return order;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
SampleSessionContext context = SampleSessionContext.get();
context.setUserId(request.getParameter("userId"));
filterChain.doFilter(request, response);
} finally {
SampleSessionContext.remove();
}
}
}
package org.hongxi.whatsmars.boot.sample.web.interceptor;
import org.hongxi.whatsmars.boot.sample.web.context.SampleSessionContext;
import org.hongxi.whatsmars.boot.sample.web.exception.BusinessException;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by shenhongxi on 2020/8/16.
*/
public class SampleSessionInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
SampleSessionContext context = SampleSessionContext.get();
if (context == null || !StringUtils.hasLength(SampleSessionContext.getUserId())) {
throw new BusinessException(BusinessException.ErrorCode.AUTH_FAIL);
}
return super.preHandle(request, response, handler);
}
}
package org.hongxi.whatsmars.boot.sample.web.model;
/**
* Created by shenhongxi on 2020/8/16.
*/
public class JsonResponse<T> {
public static final int SUCCESS_CODE = 0;
// 错误码,0表示成功
private int code;
// 错误原因
private String msg;
// 服务器下发数据时间
private long millisecond;
private T data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public long getMillisecond() {
return millisecond;
}
public void setMillisecond(long millisecond) {
this.millisecond = millisecond;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static <T> JsonResponse success(T value) {
JsonResponse<T> response = new JsonResponse<>();
response.setCode(SUCCESS_CODE);
response.setMsg("ok");
response.setMillisecond(System.currentTimeMillis());
response.setData(value);
return response;
}
public static JsonResponse error(int ec, String em) {
JsonResponse response = new JsonResponse<>();
response.setCode(ec);
response.setMsg(em);
response.setMillisecond(System.currentTimeMillis());
return response;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册