предисловие
В последнее время, поскольку системе необходимо получить доступ к новому платежному каналу, вообще говоря, использованиеRestApi
для доступа, но канал оплаты для этого доступа - оплата за границей.WebService, Мы принципиально не используем WS в реальном бизнесе, поэтому я проверил некоторые материалы и записал WS, используемую в наших собственных проектах.
Обзор веб-сервиса
- Что такое веб-сервис
Технология веб-сервисов позволяет различным приложениям, работающим на разных машинах, обмениваться данными или интегрироваться друг с другом, не прибегая к дополнительному специализированному программному или аппаратному обеспечению сторонних производителей. Приложения, реализованные в соответствии со спецификацией веб-сервиса, могут обмениваться данными друг с другом независимо от используемого ими языка, платформы или внутреннего протокола.
Проще говоря, WebService — это технология удаленного вызова на разных языках программирования и платформах операционных систем. - WebServiceТехническая поддержка
в основном для пониманияXML和XSD
,SOAP
,WSDL
,UDDI
, пожалуйста, обратитесь к энциклопедии Baidu за подробностями:Web Service
Обзор Apache-CXF
- Что такое Apache-CXF
Apache CXF – это платформа для служб с открытым исходным кодом. CXF помогает создавать и разрабатывать службы с использованием интерфейсных программных API, таких как JAX-WS и JAX-RS. Эти службы могут поддерживать различные протоколы, такие как: SOAP, XML/HTTP, RESTful HTTP или CORBA, и могут работать на различных транспортных протоколах, таких как: HTTP, JMS или JBI,
CXF значительно упрощает создание сервисов и в то же время легко интегрируется со Spring.
За подробностями обращайтесь к официальному:Apache CXF - Спецификация JAX-WS
JAX-WS расшифровывается как Java API для веб-сервисов на основе XML. JAX-WS — это модель программирования, поддерживающая стандартную модель разработки клиентских приложений веб-службы на основе аннотаций и упрощающая разработку приложений.
JAX-WS — это API языка программирования Java для создания веб-сервисов.- На стороне сервера пользователю нужно только определить интерфейс SEI (интерфейс конечной точки службы), который необходимо реализовать для удаленного вызова через язык Java, и предоставить соответствующую реализацию, которую можно опубликовать как интерфейс веб-службы, вызвав публикацию службы. интерфейс JAX-WS.
- На стороне клиента пользователи могут создавать прокси (заменяя удаленные службы локальными объектами) через API JAX-WS для осуществления вызовов на стороне удаленного сервера. Конечно, JAX-WS также предоставляет набор вызовов API, которые работают с базовыми сообщениями.Вы можете напрямую использовать сообщения SOAP или сообщения XML для отправки запросов через Dispatch или использовать Provider для обработки сообщений SOAP или XML.
- Общие ссылки на аннотацииСводка аннотаций WebService
Springboot интегрирует примеры CXF
Далее мы продемонстрируем, как публиковать услуги простым примером, как проводить обслуживание звонков.
Сборка сервера
- Создать проект
spring-boot-cxf-service
- Внедрение зависимостей maven
<dependencies> <!--spring-boot-starter--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!--lombok懒人依赖 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--test依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--cxf依赖 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.2.5</version> </dependency> <!--commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> <scope>provided</scope> </dependency> </dependencies>
- Создайте необходимые сущности
1.NBAPlayer.java
2.@Data @Builder @AllArgsConstructor @NoArgsConstructor public class NBAPlayer { String name; String team; List<String> teams; String description; Position position; @Override public String toString() { return "NBA现役球员" + name + ",司职" + position.value + "现效力于" + team + ",曾效力球队" + teams.toString(); } }
Positon.java
3.public enum Position { FORWARD("小前锋"), SHOOTING("控球後衛"); String value; Position(String value) { this.value = value; } public String value() { return value; } public static Position fromValue(String v) { for (Position c : Position.values()) { if (c.value.equals(v)) { return c; } } throw new IllegalArgumentException(v); } }
NBAPlayerSoapService.java
4.@WebService(targetNamespace = WsConst.NAMESPACE_URI, name = "NBAPlayerSoap") public interface NBAPlayerSoapService { /** * description 根据姓名获取球员信息 * date 2019/10/15 * * @param NBAPlayerName * @return cn.forward.springboot.cxf.service.entity.NBAPlayer */ @WebMethod(operationName = "getNBAPlayerByName") NBAPlayer getNBAPlayerByName(@WebParam(name = "NBAPlayerName") String NBAPlayerName); /** * description 获取球员列表 * date 2019/10/15 * * @return java.util.List<cn.forward.springboot.cxf.service.entity.NBAPlayer> */ @WebMethod List<NBAPlayer> getNBAPlayerList(); }
NBAPlayerSoapImpl.java
5.@WebService( targetNamespace = WsConst.NAMESPACE_URI, //wsdl命名空间 name = "NBAPlayerSoap", //portType名称 客户端生成代码时 为接口名称 serviceName = "NBAPlayerSoapService", //服务name名称 portName = "NBAPlayerPortName", //port名称 endpointInterface = "cn.forward.springboot.cxf.service.service.NBAPlayerSoapService") public class NBAPlayerSoapImpl implements NBAPlayerSoapService { @Override public NBAPlayer getNBAPlayerByName(String name) { List<NBAPlayer> nbaPlayers = getNBAPlayerList(); AtomicReference<NBAPlayer> player = new AtomicReference<>(nbaPlayers.get(new Random().nextInt(2))); nbaPlayers.forEach(nbaPlayer -> { if (nbaPlayer.getName().equals(name)) { player.set(nbaPlayer); } }); return player.get(); } @Override public List<NBAPlayer> getNBAPlayerList() { return generatorList(); } public List<NBAPlayer> generatorList() { List<NBAPlayer> resultList = new ArrayList<>(); NBAPlayer LBJ = new NBAPlayer(); LBJ.setName("勒布朗·詹姆斯"); LBJ.setTeam("洛杉矶湖人"); LBJ.setTeams(Arrays.asList("克里夫蘭騎士(2003−2010)", "邁阿密熱火(2010−2014)")); LBJ.setPosition(Position.FORWARD); LBJ.setDescription(LBJ.toString()); resultList.add(LBJ); NBAPlayer WS = new NBAPlayer(); WS.setName("罗素·威斯布鲁克"); WS.setTeam("休斯頓火箭"); WS.setTeams(Arrays.asList("奧克拉荷馬雷霆 (2008-2019)")); WS.setPosition(Position.SHOOTING); WS.setDescription(WS.toString()); resultList.add(WS); return resultList; } }
WsConst.java
6.public class WsConst { public static final String NAMESPACE_URI = "http://www.lqdev.cn/webservice"; }
CxfWebServiceConfig.java
Меры предосторожности:При настройке ServletRegistrationBean вам необходимо обратить внимание на установку имени метода или имени компонента, чтобы оно не совпадало с именем класса DispatcherServlet по умолчанию, что приведет к тому, что исходный интерфейс mvc станет непригодным для использования, поскольку он будет перезаписан. Путь для изменения доступа можно изменить, установив ServletRegistrationBean, но в то же время следует отметить, что имя компонента должно быть установлено как cxfServletRegistration, иначе будет зарегистрировано несколько CXFServlet. По конкретным причинам см. класс автоматической настройки: org.apache.cxf.spring.boot.autoconfigure.CxfAutoConfiguration.@Configuration public class CxfWebServiceConfig { //这里需要注意 由于springmvc 的核心类 为DispatcherServlet //此处若不重命名此bean的话 原本的mvc就被覆盖了。可查看配置类:DispatcherServletAutoConfiguration //一种方法是修改方法名称 或者指定bean名称 //这里需要注意 若beanName命名不是 cxfServletRegistration 时,会创建两个CXFServlet的。 //具体可查看下自动配置类:Declaration org.apache.cxf.spring.boot.autoconfigure.CxfAutoConfiguration //也可以不设置此bean 直接通过配置项 cxf.path 来修改访问路径的 @Bean("cxfServletRegistration") public ServletRegistrationBean dispatcherServlet() { //注册servlet 拦截/NBA 开头的请求 不设置 默认为:/services/* return new ServletRegistrationBean(new CXFServlet(), "/NBA/*"); } /** * 申明业务处理类 当然也可以直接 在实现类上标注 @Service * @author ShiFan */ @Bean public NBAPlayerSoapService authorService() { return new NBAPlayerSoapImpl(); } /** * 非必要项 */ @Bean(name = Bus.DEFAULT_BUS_ID) public SpringBus springBus() { SpringBus springBus = new SpringBus(); return springBus; } /** * 发布endpoint */ @Bean public Endpoint endpoint(NBAPlayerSoapService NBAPlayerSoap) { EndpointImpl endpoint = new EndpointImpl(springBus(), NBAPlayerSoap); //发布地址 endpoint.publish("/player"); return endpoint; } }
Таким образом, изменить путь доступа также можно с помощью настройки элемента: cxf.path. Его URL-адрес доступа по умолчанию: / services - Создайте класс запуска и одновременно запустите приложение
@SpringBootApplication
@Slf4j
public class SpringBootCxfServiceApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootCxfServiceApplication.class, args);
log.info("spring-boot-cxf-service启动!");
}
}
Просмотр журнала ввода
2019-10-15 15:49:17.964 INFO 16100 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-10-15 15:49:17.967 INFO 16100 --- [ main] .f.s.c.s.SpringBootCxfServiceApplication : Started SpringBootCxfServiceApplication in 3.35 seconds (JVM running for 4.454)
2019-10-15 15:49:17.969 INFO 16100 --- [ main] .f.s.c.s.SpringBootCxfServiceApplication : spring-boot-cxf-service启动!
- контрольная работа
доступhttp://localhost:8080/NBA/player?wsdlпроверять:
Сборка клиента
- Создать проект
spring-boot-cxf-client
- Внедрение зависимостей maven
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.2.5</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.5.17</version> </dependency> </dependencies>
- Создайте файл wsdl и используйте плагин: cxf-codegen-plugin для создания связанных классов.
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- cxf-codegen-plugin --> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>3.2.5</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <sourceRoot>${project.basedir}/src/main/java</sourceRoot> <wsdlOptions> <wsdlOption> <wsdl>src/main/resources/wsdl/player.wsdl</wsdl> <wsdlLocation>classpath:wsdl/player.wsdl</wsdlLocation> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
提示:
Поместите файл wsdl в каталог main/resources/wsdl. После выполнения команды mvn generate-sources соответствующий файл класса будет создан автоматически. Скопируйте соответствующие файлы классов в каталог src/java. Или также можно указать sourceRoot напрямую - Создавайте классы конфигурации, классы доступа и т. д.
-
WsCont.java
public class WsConst { public static final String SERVICE_ADDRESS= "http://localhost:8080/NBA/player?wsdl"; }
-
CxfClientConfig.java
@Configuration public class CxfClientConfig { /** * 采用代理方式 * * @return NBAPlayerSoap */ @Bean public NBAPlayerSoap createAuthorPortTypeProxy() { JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); jaxWsProxyFactoryBean.setServiceClass(NBAPlayerSoap.class); jaxWsProxyFactoryBean.setAddress(WsConst.SERVICE_ADDRESS); return (NBAPlayerSoap) jaxWsProxyFactoryBean.create(); } /** * 采用动态工厂方式 不需要指定服务接口 */ @Bean public Client createDynamicClient() { JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client = dcf.createClient(WsConst.SERVICE_ADDRESS); return client; } }
-
NBAPlayerController.java
@RestController @RequestMapping("/nba/player") public class NBAPlayerController { @Resource NBAPlayerSoap nbaPlayerSoap; /** * description 根据球员名称获取球员信息 * date 2019/10/15 * * @param nbaPlayerName * @return cn.lqdev.webservice.NbaPlayer */ @GetMapping("/getNBAPlayerByName") public NbaPlayer getNBAPlayerByName(@RequestParam("nbaPlayerName") String nbaPlayerName) { return nbaPlayerSoap.getNBAPlayerByName(nbaPlayerName); } /** * description 获取全部球员信息 * date 2019/10/15 * @return java.util.List<cn.lqdev.webservice.NbaPlayer> */ @GetMapping("/getNBAPlayerList") public List<NbaPlayer> getNBAPlayerList() { return nbaPlayerSoap.getNBAPlayerList(); } }
- Создать класс запуска, протестировать
доступ:http://localhost:8081/nba/player/getNBAPlayerByName?nbaPlayerName=Леброн Джеймс@SpringBootApplication @Slf4j public class SpringBootCxfClientApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCxfClientApplication.class, args); log.info("spring-boot-cxf-client启动!"); } }
Результаты проверки:{ description: "NBA现役球员勒布朗·詹姆斯,司职小前锋现效力于洛杉矶湖人,曾效力球队[克里夫蘭騎士(2003−2010), 邁阿密熱火(2010−2014)]", name: "勒布朗·詹姆斯", position: "FORWARD", team: "洛杉矶湖人", teams: [ "克里夫蘭騎士(2003−2010)", "邁阿密熱火(2010−2014)" ] }
6. Справочные статьи
Суммировать
В этой статье в основном рассказывается о процессе создания Springboot сервисов WebService на основе CXF.