Spring MVCカスタムパラメータ注記と解析

17139 ワード

バックグラウンド管理システムでは、ログインしたユーザー情報をHandlerで取得する必要があることがよくあります.ログインしたユーザーのストレージはsessionまたはredisに保存されている可能性があります.では、Handlerがユーザー情報を迅速に取得し、ユーザーデータがどこに保存されているかを気にする必要はありません.さらに、その後のログインしたユーザーデータの保存の移行もHandlerを変更する必要はありません.期待される効果は次のとおりです.
@PostMapping("/user/getUserInfo")
@ResponseBody
public ResponseVO<UserInfo> getUserInfo(@Login UserInfo userInfo) {
	ResponseVO<UserInfo> responseVO = new ResponseVO<>();
	responseVO.setBizObj(userInfo);
	return responseVO;
}

では、上記の効果をどのように実現するのでしょうか.
1、自分の注釈を定義する
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author katasea
 * 2020/5/18 17:43
 */

@Target(ElementType.PARAMETER)//         
@Retention(RetentionPolicy.RUNTIME)
public @interface Login {
}


2、解析カスタムArgumentResolverの作成
本明細書で使用するユーザオブジェクトUserInfo読者は、気にすることなく、具体的には自分のユーザクラスに置き換えればよい
import com.health.bean.po.Login;
import com.health.bean.po.UserInfo;
import com.health.util.Global;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.data.redis.core.RedisTemplate;
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 javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author katasea
 * 2020/6/5 10:38
 */
@Configuration
public class LoginHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
	//        redis,          
	@Resource
	private RedisTemplate<String,Object> redisTemplate;

	private Logger logger = LoggerFactory.getLogger(this.getClass());
	//      Login       UserInfo【         】,     
	@Override
	public boolean supportsParameter(MethodParameter methodParameter) {
		return (null != methodParameter.getParameterAnnotation(Login.class) && UserInfo.class == methodParameter.getParameterType());
	}

	//               
	@Override
	public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
		HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
		try{ 
			UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(request.getAttribute(Global.TOKEN));
			return userInfo;
		}catch (Exception e) { 
			return null;
		}
	}
}

3、遮断器の配置を増やす
以下にSpringBootブロッキング構成項目を示します.
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author katasea
 * 2020/5/12 13:48
 */
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
		@Resource
		LoginHandlerMethodArgumentResolver userArgumentResolver; 
	
		//          ,           。
		@Override
		public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
			argumentResolvers.add(userArgumentResolver);
		}
}

4、Handlerはログインユーザーオブジェクトの取得を試みる
//        
@PostMapping("/user/getUserInfo")
@ResponseBody
public UserInfo getUserInfo(@Login UserInfo userInfo) { 
	return userInfo;
}