springboot使⽤⾃定义参数解析器需求:在⽤户已经登录后请求别的接⼝时注⼊⽤户对象
1、⾃定义需要拦截的参数注解和⽤户实体对象
package io.xiongdi.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 登录⽤户注解
* @author wujiaxing
* @date 2019-06-30
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
package ity;
import batisplus.annotation.TableId;
import batisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* ⽤户实体类
* @author wujiaxing
*/
@Data
@Builder
@TableName("tb_user")
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1315432620351507739L;
public UserEntity(){}
public UserEntity(long userId, String username, String mobile, String password, LocalDateTime createTime) {
this.userId = userId;
this.username = username;
this.password = password;
}
/**
* ⽤户ID
*/
@TableId
private long userId;
/**
* ⽤户名
*/
private String username;
/**
* 电话号码
*/
private String mobile;
/**
* 密码
*/
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
}
2、⾃定义参数解析器类,实现 HandlerMethodArgumentResolver 接⼝,并实现其⽅法
package solver;
import io.xiongdi.annotation.LoginUser;
import ity.UserEntity;
import io.xiongdi.interceptor.AuthorizationInterceptor;
import io.xiongdi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.t.request.NativeWebRequest;
import org.t.request.RequestAttributes;
import org.hod.support.HandlerMethodArgumentResolver;
import org.hod.support.ModelAndViewContainer;
/**
* ⽅法参数解析器接⼝,这个接⼝是SpringMVC参数解析绑定的核⼼接⼝。
* 不同的参数类型绑定都是通过实现这个接⼝来实现。
* 也可以通过实现这个接⼝来⾃定义参数解析器
* @author wujiaxing
* @date 2019-06-30
*/
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private UserService userService;
/**
* 该解析器是否⽀持parameter参数的解析
* @param parameter 拦截到的参数
* @return是否符合我们的拦截规则
* <p>
* isAssignableFrom⽅法作⽤是判断参数类型是否为UserEntity类或是⽗类或是⽗接⼝
* </p>
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return ParameterType().isAssignableFrom(UserEntity.class) && parameter.hasParameterAnnotation(LoginUser.class);
}
/**
* <p>
* 将⽅法参数从给定请求(webRequest)解析为参数值并返回
* 请求顺序:
* 1.进⼊,拦截有token请求头的⽤户,说明是验证过的
* 2.进⼊⾃定义参数解析器supportsParameter⽅法,解析带有LoginUser注解并且类UserEntity或⽗类的参数
* 3.进⼊⾃定义参数解析器resolveArgument⽅法,将存在作⽤域⾥的userid拿出来查询到user⽤户信息,赋给UserEntity参数
* </p>
* @param parameter
* @param mavContainer
* @param webRequest
* @param binderFactory
* @return
* @throws Exception
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { // 从请求作⽤域中获取userid
Object o = Attribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
if (o == null) {
return null;
}
UserEntity userEntity = ById((long) o);
return userEntity;
}
}
3、将⾃定义的参数解析器添加到 spring boot
package fig;
import io.xiongdi.interceptor.AuthorizationInterceptor;
import solver.LoginUserHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import t.annotation.Configuration;
import org.hod.support.HandlerMethodArgumentResolver;
import org.springframework.fig.annotation.CorsRegistry;
import org.springframework.fig.annotation.InterceptorRegistry;
import org.springframework.fig.annotation.WebMvcConfigurer;
import java.util.List;
/**
* @author wujiaxing
* <p>
* 此配置类可配置、参数解析器、返回值解析器、跨域⽀持等等
* </p>
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AuthorizationInterceptor authorizationInterceptor;
@Autowired
private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
/**
* 配置
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authorizationInterceptor).addPathPatterns("/api/**");
}
/**
* 跨域⽀持配置
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowCredentials(true).allowedOrigins("*").allowedMethods("GET", "PUT", "DELETE", "POST", "OPTIONS").maxAge(3600); }
/**
* 参数解析配置
* @param resolvers
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(loginUserHandlerMethodArgumentResolver);
}
mybatis和springmvc}
4、配置已经好了,可以写⼀个接⼝测试⼀下了
package ller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.xiongdi.annotation.Login;
import io.xiongdi.annotation.LoginUser;
import io.xiongdimon.utils.R;
import ity.UserEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author wujiaxing
* @date 2019-07-07
*/
@Api(tags = "测试接⼝")
@RestController
@RequestMapping("/api")
public class ApiTestController {
// 测试⽤这个⽅法就⾏,下⾯两个⽅法是别的功能的,@Login 注解也是⾃定义的,测试时可以去掉09:11:38
@Login
@ApiOperation(value = "获取⽤户对象", response = UserEntity.class)
@GetMapping("userInfo")
public R userInfo(@LoginUser UserEntity userEntity) {
return R.ok().put("user", userEntity);
}
@Login
@ApiOperation("获取⽤户ID")
@GetMapping("userId")
public R userId(@RequestAttribute("userId") long userId) {
return R.ok().put("userId", userId);
}
@ApiOperation("忽略token测试")
@GetMapping("notToken")
public R notToken() {
return R.ok().put("msg", "⽆需token也能正常登录");
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论