所以我必须说所有的websocket教程/示例看起来都很简单,但是你似乎真的需要挖掘才能找到简单例子中遗漏的非常重要的信息.我的webapp使用前端有SockJs的Spring 4 Stomp消息代理,我有很多问题.
目前,如果我在没有启用SockJs()的情况下向StompEndpointRegistry添加端点,然后使用dojo的dojox / socket在前端声明我的套接字,firefox 28将打开websocket就好了.但是,我需要在ie8和IE9中支持,所以我切换到了SockJs.使用AbstractAnnotationConfigdispatcherServletinitializer,我花了很多时间来弄清楚如何确保所有过滤器和servlet都设置为使用异步(在Web上非常稀疏的文档).一旦我解决了这个问题,我现在可以在firefox中使用它,但只能使用xhr_streaming.将sessioncookieNeeded设置为true,IE9默认尝试使用iframe进行连接,但是,它失败:
LOG: opening Web Socket... LOG: opening transport: iframe-HTMLfile url:rest/hello/904/ft3apk1g RTO:1008 LOG: Closed transport: iframe-HTMLfile SimpleEvent(type=close,code=1006,reason=Unable to load an iframe (onload timeout),wasClean=false) LOG: opening transport: iframe-xhr-polling url:rest/hello/904/bf63eisu RTO:1008 LOG: Closed transport: iframe-xhr-polling SimpleEvent(type=close,wasClean=false) LOG: Whoops! Lost connection to undefined
如果我将所需的cookie设置为false,IE将使用xdr-streaming并正常工作,它会丢失请求中的JsessionID cookie,反过来我失去了在控制器中获取Principal的能力,这对我来说很重要.我在spring security中启用了相同的origin x frame header,我已经验证了请求中是否存在标题,但它没有帮助.所以我想知道如何A)让Spring和SockJs在firefox中使用WebSocket传输正确协商,并且B)让ie8和9正确使用iframe传输,这样我就可以保留cookie.
这是我的配置/代码:
网络应用配置:
public class WebAppInitializer extends AbstractAnnotationConfigdispatcherServletinitializer { @OverrIDe public voID onStartup(ServletContext servletContext) throws servletexception { super.onStartup(servletContext); Map
Spring MVC配置:
@Configuration@EnableWebMvc@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)@ComponentScan(basePackages = "x.controllers") // Only scan for controllers. Other classes are scanned in the parent's root contextpublic class SpringMvcConfig extends WebMvcConfigurerAdapter { @OverrIDe public voID addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/CSS/**").addResourceLocations("/CSS/").setCachePeriod(31556926); registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(31556926); registry.addResourceHandler("/Js/**").addResourceLocations("/Js/").setCachePeriod(31556926); } @OverrIDe public voID configureMessageConverters(List
Spring root上下文配置:
@Configuration@EnableTransactionManagement@ComponentScan(basePackages = {"com.x.services"},// scan for all annotated classes for the root context OTHER than controllers -- those are in the child web context. also don't rescan these config files excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class),@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Configuration.class) })public class ServiceConfig { @Bean public DefaultAnnotationHandlerMapPing defaultAnnotationHandlerMapPing() { DefaultAnnotationHandlerMapPing handlerMapPing = new DefaultAnnotationHandlerMapPing(); handlerMapPing.setAlwaysUseFullPath(true); handlerMapPing.setDetectHandlersInAncestorContexts(true); return handlerMapPing; } @Bean public DefaultConversionService defaultConversionService() { return new DefaultConversionService(); } @Bean(name = "kmlContext") public JAXBContext kmlContext() throws JAXBException { return JAXBContext.newInstance("net.opengis.kml"); } @Bean(name = "ogcContext") public JAXBContext ogcContext() throws JAXBException { return JAXBContext.newInstance("net.x"); }}
春季安全:
@Configuration@EnableWebMvcSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { @autowired private CustomUserDetailsService userDetailsService; @autowired private CustomAuthenticationProvIDer customAuthenticationProvIDer; @autowired public voID configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @OverrIDe protected voID configure(httpSecurity http) throws Exception { AuthenticationProvIDer rememberMeAuthenticationProvIDer = rememberMeAuthenticationProvIDer(); TokenBasedRememberMeServices tokenBasedRememberMeServices = tokenBasedRememberMeServices(); ListIDer> authenticationProvIDers = new ArrayListIDer>(2); authenticationProvIDers.add(rememberMeAuthenticationProvIDer); authenticationProvIDers.add(customAuthenticationProvIDer); AuthenticationManager authenticationManager = authenticationManager(authenticationProvIDers); http .csrf().disable() //.headers().disable() .headers().addheaderWriter(new XFrameOptionsheaderWriter(XFrameOptionsheaderWriter.XFrameOptionsMode.SAMEORIGIN)) .and() .authenticationProvIDer(customAuthenticationProvIDer) .addFilter(new RememberMeAuthenticationFilter(authenticationManager,tokenBasedRememberMeServices)) .rememberMe().rememberMeServices(tokenBasedRememberMeServices) .and() .authorizeRequests() .antMatchers("/Js/**","/CSS/**","/img/**","/login","/processLogin").permitAll() .antMatchers("/index.Jsp","/index").hasRole("USER") .antMatchers("/admin","/admin.Jsp","/Js/saic/Jswe/admin/**").hasRole("admin") .and() .formLogin().loginProcessingUrl("/processLogin").loginPage("/login").usernameParameter("username").passwordParameter("password").permitAll() .and() .exceptionHandling().accessDenIEdPage("/login") .and() .logout().permitAll(); } @OverrIDe public voID configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/Js/**","/img/**"); } @Bean public BCryptPasswordEncoder bCryptPasswordEncoder(){ return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(ListIDer> authenticationProvIDers) { return new ProvIDerManager(authenticationProvIDers); } @Bean public TokenBasedRememberMeServices tokenBasedRememberMeServices() { return new TokenBasedRememberMeServices("testKey",userDetailsService); } @Bean public AuthenticationProvIDer rememberMeAuthenticationProvIDer() { return new org.springframework.security.authentication.RememberMeAuthenticationProvIDer("testKey"); } protected voID registerauthentication(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); }}
WebSocket消息代理配置:
@Configuration@EnableWebSocketMessagebroker@EnableSchedulingpublic class WebSocketConfig extends AbstractWebSocketMessagebrokerConfigurer { @OverrIDe public voID configureMessagebroker(MessagebrokerRegistry config) { config.enableSimplebroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @OverrIDe public voID registerStompEndpoints(StompEndpointRegistry registry) { SockJsServiceRegistration registration = registry.addEndpoint("/hello").withSockJs().setClIEntlibraryUrl("http://localhost:8084/swtc/Js/sockJs-0.3.4.min.Js"); registration.setWebSocketEnabled(true); //registration.setSessioncookieNeeded(false); } @OverrIDe public voID configureClIEntInboundChannel(ChannelRegistration registration) { registration.taskExecutor().corePoolSize(4).maxPoolSize(8); } @OverrIDe public voID configureClIEntOutboundChannel(ChannelRegistration registration) { registration.taskExecutor().corePoolSize(4).maxPoolSize(8); }}
WebSocket控制器:
@Controllerpublic class WebSocketController { @MessageMapPing({"/hello","/hello/**"}) @SendTo("/topic/greetings") // in order to get principal,you must set cookiesNeeded in WebSocketConfig,which forces IE to use iframes,which doesn't seem to work public AJAXResponse
最后,我的HTML中的JavaScript用于测试:
总结 以上是内存溢出为你收集整理的Spring 4 AbstractWebSocketMessageBrokerConfigurer与SockJS无法正确协商传输全部内容,希望文章能够帮你解决Spring 4 AbstractWebSocketMessageBrokerConfigurer与SockJS无法正确协商传输所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)