zoukankan      html  css  js  c++  java
  • SpringBoot +CXF 发布WebService服务后其他http请求不能使用

    一、概述

       因为项目需要,需要再原先项目中发布或者调用WebService服务,考虑到集成Springboot框架,于是采用CXF框架。
       WebService注册服务如下:

     1 @Configuration
     2 public class CxfWebServiceConfig {
     3 
     4 
     5     @Autowired
     6     private HelloWebService helloWebService;
     7 
     8     @Bean
     9     public ServletRegistrationBean dispatcherServlet() {
    10         return new ServletRegistrationBean(new CXFServlet(), "/service/*");//发布服务名称
    11     }
    12 
    13     @Bean(name = Bus.DEFAULT_BUS_ID)
    14     public SpringBus springBus() {
    15         return new SpringBus();
    16     }
    17 
    18     public HelloWebService helloWebService(){
    19         return new HelloWebServiceImpl();
    20     }
    21 
    22     @Bean
    23     public Endpoint endpoint(){
    24         EndpointImpl endpoint = new EndpointImpl(springBus(),helloWebService);
    25         endpoint.publish("/HelloWebService");
    26         return endpoint;
    27     }
    28 
    29 }

    在将CXF集成之后,WebService服务能够正常访问,但是原先的http服务不能访问
       因为springboot程序中默认注册的是 dispatcherServlet,在发不了WebService服务之后,相当于手动配置 ServletRegistrationBean,这时springboot不会再去注册默认的dispatcherServlet,解决办法就是需要我们在启动类里手动去注册一个dispatcherServlet

    spring boot中注册Servlet的两种方式

    但spring boot把tomcat都给隐藏了,更别说web.xml了。好在提供了另外的方式配置servlet。
    1.@WebServlet注解:
    这个是javaee的注解,是servlet3.0以后提供的。spring boot会扫描这个注解,并将这个注解注解的类注册到web容器中作为一个servlet。
    但是DispatcherServlet并不是自定义的servlet,而是框架提供的servlet,所以此方法不行。
    2.ServletRegistrationBean:
    这个bean是由spring boot提供专门来注册servlet的,可以象注册bean一样去配置servlet。

     1     @Bean
     2     public ServletRegistrationBean dispatcherServlet() {
     3         //注解扫描上下文
     4         AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
     5         //项目包名
     6         applicationContext.scan("com.surfilter.*");
     7         DispatcherServlet rest_dispatcherServlet = new DispatcherServlet(applicationContext);
     8         ServletRegistrationBean registrationBean = new ServletRegistrationBean(rest_dispatcherServlet);
     9         registrationBean.setLoadOnStartup(1);
    10         registrationBean.addUrlMappings("/*");
    11         //一定要加上此行
    12         registrationBean.setName("rest_dispatcherServlet");
    13         return registrationBean;
    14     }        
    其中需要注意的是registration.setName("rest_dispatcherServlet"),这个语句很重要,因为name相同的ServletRegistrationBean只有一个会生效,也就是说,后注册的会覆盖掉name相同的ServletRegistrationBean。
    如果不指定,默认为“dispatcherServlet”而spring boot提供的DispatcherServlet的name就是“dispatcherServlet”。可以在spring boot的DispatcherServletAutoConfiguration类中找到:
     1 public ServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
     2             ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet, new String[]{this.serverProperties.getServletMapping()});
     3             registration.setName("dispatcherServlet");
     4             registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());
     5             if(this.multipartConfig != null) {
     6                 registration.setMultipartConfig(this.multipartConfig);
     7             }
     8 
     9             return registration;
    10         }
    11     }

    所以为了不覆盖默认的dispatcherServlet,必须指定一个别的名称

    同时,在自定义的DispathcerServlet绑定的配置类上,要配置报扫描的话,必须要加上@EnableWebMvc注解,不然不会扫描@Contrller注解。

    1 @RestController
    2 @RequestMapping("/api/1.0/hello")
    3 @EnableWebMvc
    4 public class RestController {
    5     ......
    6 }

    屏蔽rest服务DispatcherServlet对静态资源的访问

    最后还有一个小问题,因为想让额外配置的一个DispatcherServlet专门用于提供rest服务,但是这样配置之后,访问localhost/rest/时会访问到页面等静态资源,感觉怪怪的。
    因为spring boot默认是对静态资源做了映射的,但如果不想要访问到任何静态的资源,可以修改这个映射。
    两种方式:
    1.在application.yml中配置:

    1 spring:
    2   mvc:
    3     #默认为/**
    4     static-path-pattern: /**
    5   resources:
    6     #默认为classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 。配置多个路径,中间用逗号隔开。
    7     static-locations: 
    如果在这里配置,就会影响整个springboot项目。但默认的DispatcherServlet是需要访问静态资源的,所以不能在这里配置。
    2.继承WebMvcConfigurerAdapter的java类中配置:
    1 @Configuration
    2 @EnableWebMvc
    3 public class Cfg_View extends WebMvcConfigurerAdapter{
    4     @Override
    5     public void addResourceHandlers(ResourceHandlerRegistry registry) {
    6         registry.addResourceHandler("/**");
    7     }
    8 }
    重写addResourceHandlers方法,只指定resourceHandler,不指定resourceLocation,这样写就能够使其拦截掉所有对静态资源的访问,并且不会返回任何静态资源。这里的配置是可指定的,只需要让负责rest服务的DispatcherServlet的上下文扫描这个配置类就可以了。不会影响默认的DispatcherServlet
  • 相关阅读:
    iOS面试题及答案大总结
    iOS 画音频波形曲线 根据音频数据版
    iPhone-获取网络数据或者路径的文件名
    python语言使用yaml 管理selenium元素
    出现事故后我们怎么复盘分析
    如何提升测试质量,减少漏测
    robotframework环境搭建
    如何做ui自动化---步骤详解
    Jenkins报错Caused: java.io.IOException: Cannot run program "sh" (in directory "D:JenkinsJenkins_homeworkspacejmeter_test"): CreateProcess error=2, 系统找不到指定的文件。
    使用jmeter使用Jenkins发送自定义消息内容
  • 原文地址:https://www.cnblogs.com/lgjava/p/12462192.html
Copyright © 2011-2022 走看看