因为User类实现了Principal ,springmvc对Principal已经定义了自己的处理方式
ServletRequestMethodArgumentResolver
处理request相关的参数:WebRequest,ServletRequest,MultipartRequest,HttpSession,Principal,Locale,InputStream,Reader
public class User implements Principal
所以自定义的HandlerMethodArgumentResolver无法生效;
因为我的系统中使用了springboot的websocket所以User需要继承Principal接口
websocket相关代码: 需要使用User的name来确定当前websocket的user信息
package com.qky.qingchi.config;
import com.qky.qingchi.entity.User;
import com.qky.qingchi.util.TokenUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptorAdapter;
import org.springframework.messaging.support.MessageHeaderAccessor;
public class UserInterceptor extends ChannelInterceptorAdapter {
/**
* 获取包含在stomp中的用户信息
*/
@Override
public Message> preSend(Message> message, MessageChannel channel) {
StompHeaderAccessor accessor =
MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
//1. 判断是否首次连接请求
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
//2. 验证是否登录
String token = accessor.getNativeHeader("token").get(0);
if (TokenUtils.isCorrect(token)) {
accessor.setUser(new WebSocketUser(TokenUtils.getUsername(token)));
return message;
} else {
return null;
}
}
//不是首次连接,已经成功登陆
return message;
}
}
解决办法:
websocket使用自定义的User类,不和系统中的User共同使用;
import java.security.Principal;
public class WebSocketUser implements Principal {
private String username;
@Override
public String getName() {
return this.username;
}
public WebSocketUser() {
}
public WebSocketUser(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
package com.qky.qingchi.entity;
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.security.Principal;
@Entity
public class User{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String password;
private String headImg;
public User() {
}
public User(Integer id) {
this.id = id;
}
public User(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getHeadImg() {
return headImg;
}
public void setHeadImg(String headImg) {
this.headImg = headImg;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("id", id)
.append("name", name)
.append("password", password)
.append("headImg", headImg)
.toString();
}
}
package com.qky.qingchi.config;
import com.qky.qingchi.entity.User;
import com.qky.qingchi.user.query.UserUtil;
import org.springframework.core.MethodParameter;
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;
public class LoginUserInfoMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public Object resolveArgument(MethodParameter arg0, ModelAndViewContainer arg1, NativeWebRequest arg2,
WebDataBinderFactory arg3) throws Exception {
System.out.println(6789);
System.out.println(UserUtil.getUser());
return UserUtil.getUser();
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
System.out.println("888:" + parameter.getParameterType());
return parameter.getParameterType().equals(User.class);
}
}
package com.qky.qingchi.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
//设置允许跨域的路径
registry.addMapping("/**")
//设置允许跨域请求的域名
.allowedOrigins("*")
//是否允许证书 不再默认开启
.allowCredentials(true)
//设置允许的方法
.allowedMethods("*")
.allowedHeaders("*")
//跨域允许时间
.maxAge(3600);
}
@Override
public void addArgumentResolvers(List argumentResolvers) {
System.out.println(12345);
System.out.println("argumentResolvers.size():" + argumentResolvers.size());
argumentResolvers.add(new LoginUserInfoMethodArgumentResolver());
System.out.println("argumentResolvers.size():" + argumentResolvers.size());
}
}
直接接受User类,我的处理方式是将reques中的header中的token直接转为User用户传入方法
@RestController
@RequestMapping("comment")
@SessionAttributes("user")
public class CommentController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@Resource
CommentRepository comRep;
@PostMapping("add")
@ResponseBody
public Comment commentAdd(User user) {
System.out.println("user:"+user);
/*Comment comment = comRep.save(VO.toComment(UserUtil.getUser()));
messagingTemplate.convertAndSendToUser("qq", "/queue/notifications", comment);*/
//获取所有说说
return null;
}
}
参考资料:
https://www.cnblogs.com/leftthen/p/5227722.html
https://blog.csdn.net/w372426096/article/details/78429172
百度搜索:Principal HandlerMethodArgumentResolver