当前位置:   article > 正文

springboot学习(三十四) springboot+stomp+sockJs在spring5.3以上报跨域问题的处理_((webmvcstompendpointregistry)registry).websocketh

((webmvcstompendpointregistry)registry).websockethandler cannot find local v

将springboot升级到2.4.0后websocket报跨域问题,报错如下:
When allowCredentials is true, allowedOrigins cannot contain the special value "*"since that cannot be set on the “Access-Control-Allow-Origin” response header. To allow credentials to a set of origins, list them explicitly or consider using “allowedOriginPatterns” instead.

经过跟代码发现是spring5.3以上的一个函数:

	/**
	 * Validate that when {@link #setAllowCredentials allowCredentials} is true,
	 * {@link #setAllowedOrigins allowedOrigins} does not contain the special
	 * value {@code "*"} since in that case the "Access-Control-Allow-Origin"
	 * cannot be set to {@code "*"}.
	 * @throws IllegalArgumentException if the validation fails
	 * @since 5.3
	 */
	public void validateAllowCredentials() {
		if (this.allowCredentials == Boolean.TRUE &&
				this.allowedOrigins != null && this.allowedOrigins.contains(ALL)) {

			throw new IllegalArgumentException(
					"When allowCredentials is true, allowedOrigins cannot contain the special value \"*\"" +
							"since that cannot be set on the \"Access-Control-Allow-Origin\" response header. " +
							"To allow credentials to a set of origins, list them explicitly " +
							"or consider using \"allowedOriginPatterns\" instead.");
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

解决办法:
1 继承SimpleUrlHandlerMapping重写getConfiguration函数

package com.iscas.base.biz.config.stomp;

import org.springframework.context.Lifecycle;
import org.springframework.context.SmartLifecycle;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * 升级springboot到2.4.0后websocket出现跨域问题处理,重写MyWebSocketHandlerMapping
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2020/11/25 13:59
 * @since jdk1.8
 */
public class MyWebSocketHandlerMapping extends SimpleUrlHandlerMapping implements SmartLifecycle {

    private volatile boolean running;


    @Override
    protected void initServletContext(ServletContext servletContext) {
        for (Object handler : getUrlMap().values()) {
            if (handler instanceof ServletContextAware) {
                ((ServletContextAware) handler).setServletContext(servletContext);
            }
        }
    }


    @Override
    public void start() {
        if (!isRunning()) {
            this.running = true;
            for (Object handler : getUrlMap().values()) {
                if (handler instanceof Lifecycle) {
                    ((Lifecycle) handler).start();
                }
            }
        }
    }

    @Override
    public void stop() {
        if (isRunning()) {
            this.running = false;
            for (Object handler : getUrlMap().values()) {
                if (handler instanceof Lifecycle) {
                    ((Lifecycle) handler).stop();
                }
            }
        }
    }

    @Override
    public boolean isRunning() {
        return this.running;
    }

    @Override
    public CorsConfiguration getCorsConfiguration(Object handler, HttpServletRequest request) {
        Object resolvedHandler = handler;
        if (handler instanceof HandlerExecutionChain) {
            resolvedHandler = ((HandlerExecutionChain) handler).getHandler();
        }
        if (resolvedHandler instanceof CorsConfigurationSource) {
//            if (!this.suppressCors && (request.getHeader(HttpHeaders.ORIGIN) != null)) {

//            }
//            return null;

            if (resolvedHandler instanceof SockJsHttpRequestHandler)  {
                String origin = request.getHeader("Origin");
                CorsConfiguration config = new CorsConfiguration();
                config.setAllowedOrigins(new ArrayList<>(Arrays.asList(origin)));
                config.addAllowedMethod("*");
                config.setAllowCredentials(true);
                config.setMaxAge(365 * 24 * 3600L);
                config.addAllowedHeader("*");
                return config;
            } else {
                return ((CorsConfigurationSource) resolvedHandler).getCorsConfiguration(request);
            }
        }
        return null;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

2 继承MyWebMvcStompEndpointRegistry重写getHandlerMapping函数

package com.iscas.base.biz.config.stomp;

import cn.hutool.core.util.ReflectUtil;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.util.MultiValueMap;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.WebMvcStompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebMvcStompWebSocketEndpointRegistration;
import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
import org.springframework.web.util.UrlPathHelper;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 升级springboot到2.4.0后websocket出现跨域问题处理,重写WebMvcStompEndpointRegistry
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2020/11/25 13:44
 * @since jdk1.8
 */
public class MyWebMvcStompEndpointRegistry extends WebMvcStompEndpointRegistry {
    public MyWebMvcStompEndpointRegistry(WebSocketHandler webSocketHandler, WebSocketTransportRegistration transportRegistration, TaskScheduler defaultSockJsTaskScheduler) {
        super(webSocketHandler, transportRegistration, defaultSockJsTaskScheduler);
    }

    public AbstractHandlerMapping getHandlerMapping() {
        Map<String, Object> urlMap = new LinkedHashMap<>();
        List<WebMvcStompWebSocketEndpointRegistration> registrations = null;
        try {
            registrations = (List<WebMvcStompWebSocketEndpointRegistration>) ReflectUtil.getFieldValue(this, "registrations");
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (WebMvcStompWebSocketEndpointRegistration registration : registrations) {
            MultiValueMap<HttpRequestHandler, String> mappings = registration.getMappings();
            mappings.forEach((httpHandler, patterns) -> {
                for (String pattern : patterns) {
                    urlMap.put(pattern, httpHandler);
                }
            });
        }
        MyWebSocketHandlerMapping hm = new MyWebSocketHandlerMapping();
        hm.setUrlMap(urlMap);
        int order = 1;
        try {
            order = (int) ReflectUtil.getFieldValue(this, "order");
        } catch (Exception e) {
            e.printStackTrace();
        }
        hm.setOrder(order);

        UrlPathHelper urlPathHelper = null;
        try {
            urlPathHelper = (UrlPathHelper) ReflectUtil.getFieldValue(this, "urlPathHelper");
        } catch (Exception e) {
            e.printStackTrace();
        }


        if (urlPathHelper != null) {
            hm.setUrlPathHelper(urlPathHelper);
        }
        return hm;
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

3 继承DelegatingWebSocketMessageBrokerConfiguration重写stompWebSocketHandlerMapping函数

package com.iscas.base.biz.config.stomp;

import cn.hutool.core.util.ReflectUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.DelegatingWebSocketMessageBrokerConfiguration;

/**
 * 升级springboot到2.4.0后websocket出现跨域问题处理,重写DelegatingWebSocketMessageBrokerConfiguration
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2020/11/25 13:12
 * @since jdk1.8
 */
@Configuration
//@Primary
//@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyDelegatingWebSocketMessageBrokerConfiguration extends DelegatingWebSocketMessageBrokerConfiguration {

//    @Bean
//    @Primary
    public HandlerMapping stompWebSocketHandlerMapping() {
        WebSocketHandler handler = decorateWebSocketHandler(subProtocolWebSocketHandler());
        MyWebMvcStompEndpointRegistry registry = new MyWebMvcStompEndpointRegistry(
                handler, getTransportRegistration(), messageBrokerTaskScheduler());

        ApplicationContext applicationContext = getApplicationContext();
        if (applicationContext != null) {
            try {
                ReflectUtil.setFieldValue(this, "applicationContext", applicationContext);
            } catch (Exception e) {
                e.printStackTrace();
            }
//            registry.setApplicationContext(applicationContext);
        }
        registerStompEndpoints(registry);
        return registry.getHandlerMapping();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

OK,问题解决了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/814743
推荐阅读
相关标签
  

闽ICP备14008679号