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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM