一、概述
因為項目需要,需要再原先項目中發布或者調用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 }
如果不指定,默認為“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:
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 }