"...src/main/resources/template/admin/ServiceImpl.ftl" did not exist on "bf7c1eebf08e362b478d00d0ef399d7a16f89ffc"
Commit b973b56c authored by trumansdo's avatar trumansdo
Browse files

自定义注解RequestBodyPlus 将json类型请求可以用json path的形式注入单个参数

parent 3c546fca
package com.ibeetl.admin.core.conf; package com.ibeetl.admin.core.conf;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.CharsetUtil;
import cn.hutool.http.Header; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.ibeetl.admin.core.annotation.RequestBodyPlus;
import com.ibeetl.admin.core.entity.CoreOrg; import com.ibeetl.admin.core.entity.CoreOrg;
import com.ibeetl.admin.core.entity.CoreUser; import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.service.CorePlatformService; import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.service.CoreUserService; import com.ibeetl.admin.core.service.CoreUserService;
import com.ibeetl.admin.core.util.ConvertUtil;
import com.ibeetl.admin.core.util.HttpRequestLocal; import com.ibeetl.admin.core.util.HttpRequestLocal;
import com.ibeetl.admin.core.util.JoseJwtUtil; import com.ibeetl.admin.core.util.JoseJwtUtil;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import jdk.nashorn.internal.ir.ReturnNode;
import org.beetl.core.GroupTemplate; import org.beetl.core.GroupTemplate;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration; import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.Conventions;
import org.springframework.core.MethodParameter;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.format.FormatterRegistry; import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.DateFormatter; import org.springframework.format.datetime.DateFormatter;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import sun.plugin2.util.ColorUtil;
@Configuration @Configuration
public class MVCConf implements WebMvcConfigurer, InitializingBean { public class MVCConf implements WebMvcConfigurer, InitializingBean {
...@@ -40,29 +76,27 @@ public class MVCConf implements WebMvcConfigurer, InitializingBean { ...@@ -40,29 +76,27 @@ public class MVCConf implements WebMvcConfigurer, InitializingBean {
// @Value("${app.name}") // @Value("${app.name}")
// String appName; // String appName;
// 开发用的模拟当前用户和机构 private String mvcTestPath;
Long useId;
Long orgId; @Autowired private Environment env;
String mvcTestPath; @Autowired private CoreUserService userService;
@Autowired Environment env; @Autowired private BeetlGroupUtilConfiguration beetlGroupUtilConfiguration;
@Autowired CoreUserService userService; @Autowired private HttpRequestLocal httpRequestLocal;
@Autowired BeetlGroupUtilConfiguration beetlGroupUtilConfiguration; @Autowired private GroupTemplate groupTemplate;
@Autowired HttpRequestLocal httpRequestLocal; @Autowired private RequestMappingHandlerAdapter adapter;
@Autowired GroupTemplate groupTemplate;
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry
registry.addInterceptor(new SessionInterceptor(httpRequestLocal, this)).addPathPatterns("/**"); .addInterceptor(new SessionInterceptor(httpRequestLocal, userService))
.addPathPatterns("/**")
.excludePathPatterns("/user/login", "/error", "/logout");
// super.addInterceptors(registry); // super.addInterceptors(registry);
} }
@Override @Override
...@@ -77,29 +111,31 @@ public class MVCConf implements WebMvcConfigurer, InitializingBean { ...@@ -77,29 +111,31 @@ public class MVCConf implements WebMvcConfigurer, InitializingBean {
} }
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() {
this.useId = env.getProperty("user.id", Long.class);
this.orgId = env.getProperty("user.orgId", Long.class);
this.mvcTestPath = env.getProperty("mvc.test.path"); this.mvcTestPath = env.getProperty("mvc.test.path");
Map<String, Object> var = new HashMap<>(5); Map<String, Object> var = new HashMap<>(5);
String appName = env.getProperty("app.name"); String appName = env.getProperty("app.name");
if (appName == null) { if (appName == null) {
var.put("appName", DEFAULT_APP_NAME); var.put("appName", DEFAULT_APP_NAME);
} }
var.put("jsVer", System.currentTimeMillis()); var.put("jsVer", System.currentTimeMillis());
groupTemplate.setSharedVars(var); groupTemplate.setSharedVars(var);
/*自定义参数解析器配置,自定义应该优先级最高*/
List<HandlerMethodArgumentResolver> argumentResolvers = CollUtil.newArrayList();
argumentResolvers.add(new RequestBodyPlusProcessor(adapter.getMessageConverters()));
argumentResolvers.addAll(adapter.getArgumentResolvers());
adapter.setArgumentResolvers(argumentResolvers);
} }
} }
class SessionInterceptor implements HandlerInterceptor { class SessionInterceptor implements HandlerInterceptor {
MVCConf conf; CoreUserService userService;
HttpRequestLocal httpRequestLocal; HttpRequestLocal httpRequestLocal;
public SessionInterceptor(HttpRequestLocal httpRequestLocal, MVCConf conf) { public SessionInterceptor(HttpRequestLocal httpRequestLocal, CoreUserService userService) {
this.conf = conf; this.userService = userService;
this.httpRequestLocal = httpRequestLocal; this.httpRequestLocal = httpRequestLocal;
} }
...@@ -116,10 +152,10 @@ class SessionInterceptor implements HandlerInterceptor { ...@@ -116,10 +152,10 @@ class SessionInterceptor implements HandlerInterceptor {
HttpSession requestSession = request.getSession(true); HttpSession requestSession = request.getSession(true);
if (requestSession.getAttribute(CorePlatformService.ACCESS_CURRENT_USER) == null) { if (requestSession.getAttribute(CorePlatformService.ACCESS_CURRENT_USER) == null) {
// 模拟用户登录,用于快速开发,未来用rember么代替? // 模拟用户登录,用于快速开发,未来用rember么代替?
CoreUser user = conf.userService.getUserById(uid); CoreUser user = userService.getUserById(uid);
Long orgId = user.getOrgId(); Long orgId = user.getOrgId();
CoreOrg org = conf.userService.getOrgById(orgId); CoreOrg org = userService.getOrgById(orgId);
List<CoreOrg> orgs = conf.userService.getUserOrg(uid, org.getId()); List<CoreOrg> orgs = userService.getUserOrg(uid, org.getId());
requestSession.setAttribute(CorePlatformService.ACCESS_CURRENT_USER, user); requestSession.setAttribute(CorePlatformService.ACCESS_CURRENT_USER, user);
requestSession.setAttribute(CorePlatformService.ACCESS_CURRENT_ORG, org); requestSession.setAttribute(CorePlatformService.ACCESS_CURRENT_ORG, org);
requestSession.setAttribute(CorePlatformService.ACCESS_USER_ORGS, orgs); requestSession.setAttribute(CorePlatformService.ACCESS_USER_ORGS, orgs);
...@@ -134,15 +170,79 @@ class SessionInterceptor implements HandlerInterceptor { ...@@ -134,15 +170,79 @@ class SessionInterceptor implements HandlerInterceptor {
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,
Object handler, Object handler,
ModelAndView modelAndView) ModelAndView modelAndView) {
throws Exception { /* do nothing */
// do nothing
} }
@Override @Override
public void afterCompletion( public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
/* do nothing */
}
}
/** 自定义注解,用json path 的方式注入json类型的参数 */
class RequestBodyPlusProcessor extends AbstractMessageConverterMethodProcessor {
private static final ThreadLocal<String> bodyLocal = ThreadLocal.withInitial(() -> null);
protected RequestBodyPlusProcessor(List<HttpMessageConverter<?>> converters) {
super(converters);
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestBodyPlus.class);
}
@Override
public Object resolveArgument(
MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory)
throws Exception { throws Exception {
// do nothing parameter = parameter.nestedIfOptional();
/*非json请求过滤*/
Class<?> parameterType = parameter.getNestedParameterType();
if (!StrUtil.containsAny(
webRequest.getHeader(HttpHeaders.CONTENT_TYPE), MediaType.APPLICATION_JSON_VALUE)) {
return ReflectUtil.newInstanceIfPossible(parameterType);
}
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
Assert.state(servletRequest != null, "No HttpServletRequest");
ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
String jsonBody =
Optional.ofNullable(bodyLocal.get())
.orElseGet(
() -> {
try {
bodyLocal.set(stringHttpMessageConverter.read(String.class, inputMessage));
} catch (IOException e) {
logger.error("can't read request body by input stream : {}", e);
}
return bodyLocal.get();
});
RequestBodyPlus requestBodyPlus = parameter.getParameterAnnotation(RequestBodyPlus.class);
JSON json = JSONUtil.parse(jsonBody);
Object parseVal = json.getByPath(requestBodyPlus.value(), parameterType);
/*TODO 待将json转成对象*/
System.out.println(JSONUtil.parse("{'users':[ {'user':{'name':'lisi'}} ]}").getByPath("users"));
return parseVal;
}
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return false;
} }
@Override
public void handleReturnValue(
Object returnValue,
MethodParameter returnType,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) {}
} }
package com.ibeetl.admin.core.web; package com.ibeetl.admin.core.web;
import com.ibeetl.admin.core.annotation.RequestBodyPlus;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import com.ibeetl.admin.core.entity.CoreOrg; import com.ibeetl.admin.core.entity.CoreOrg;
...@@ -57,9 +63,12 @@ public class IndexController { ...@@ -57,9 +63,12 @@ public class IndexController {
return view; return view;
}*/ }*/
@CrossOrigin
@PostMapping("/user/login") @PostMapping("/user/login")
public Object login(String username, String password) { public Object login(
@RequestBodyPlus("username") String username, String password, @RequestBodyPlus Map params) {
UserLoginInfo info = userService.login(username, password); UserLoginInfo info = userService.login(username, password);
System.out.println(params);
if (info == null) { if (info == null) {
throw new PlatformException("用户名密码错误"); throw new PlatformException("用户名密码错误");
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment