HandlerMethodArgumentResolver自定参数解析器无效websocket user实现Principal

因为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<HandlerMethodArgumentResolver> 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

猜你喜欢

转载自blog.csdn.net/qinkaiyuan94/article/details/82670411