Web Service,即“Web 服務”,簡寫為 WS(不是WebSocket哦),從字面上理解,它其實就是“基于 Web 的服務”。而服務卻是雙方的,有服務需求方,就有服務提供方。服務提供方對外發布服務,服務需求方調用服務提供方所發布的服務。
現階段,國內互聯網企業使用spring boot、spring cloud較多,而這兩者都是基于http通信的。但webservice仍在銀行、保險、金融機構等相關企業大量使用。那在與這些傳統企業對接時,spring boot 如何整合webservice將是一個亟需解決的問題。
目前較為方便的集成方案主要有apache提供的CXF以及Spring 自己提供的Spring-WS
Apache CXF -- WS-Security
Spring Web Services
本篇教材主要是讓大家快速上手cxf,實現基于Spring Boot 的webservice開發。
項目源碼: https://github.com/ouyushan/spring-webservice-samples
spring-cxf參考源碼: https://github.com/code-not-found/cxf-jaxws
spring-ws參考源碼: https://github.com/code-not-found/spring-ws
ide::IDEA
jdk:1.8
maven:3.6.2
spring boot:2.4.0
cxf:3.4.1
新建父工程spring-webservice-samples,對所有示例子模塊進行統一管理。
spring boot與cxf的簡單整合只需引入cxf-spring-boot-starter-jaxws,該依賴會自動引入web及cxf基礎包。
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.4.1</version>
</dependency>
新建子工程spring-cxf-client-begin、spring-cxf-server-begin,分別對應webservice 服務的客戶端和服務端。
spring-webservice-samples工程pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.ouyushan</groupId>
<artifactId>spring-webservice-samples</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Spring Web Services Samples</name>
<inceptionYear>2020</inceptionYear>
<modules>
<module>spring-cxf-client-begin</module>
<module>spring-cxf-server-begin</module>
</modules>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
</dependencies>
</project>
spring-cxf-server-begin服務pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.ouyushan</groupId>
<artifactId>spring-cxf-server-begin</artifactId>
<name>spring-cxf-server-begin</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring-cxf-client-begin服務pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.ouyushan</groupId>
<artifactId>spring-cxf-client-begin</artifactId>
<name>spring-cxf-client-begin</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
服務端主要基于User實體類提供用戶查詢等相關功能,然后通過cxf向外發布接口供客戶端調用。
package org.ouyushan.cxf.entity;
import java.io.Serializable;
/**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/11/26 14:42
*/
public class User implements Serializable {
private static final long serialVersionUID=-3628469724795296287L;
private String userId;
private String userName;
private String email;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId=userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName=userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email=email;
}
public User() {
}
public User(String userId, String userName, String email) {
this.userId=userId;
this.userName=userName;
this.email=email;
}
@Override
public String toString() {
return "User{" +
"userId='" + userId + '\'' +
", userName='" + userName + '\'' +
", email='" + email + '\'' +
'}';
}
}
package org.ouyushan.cxf.service;
import org.ouyushan.cxf.entity.User;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/11/26 14:42
*/
@WebService(targetNamespace="http://ws.cxf.ouyushan.org/")
public interface UserService {
@WebMethod
public String getUserName(
/* 指定入參名稱為userId 默認為arg0*/
@WebParam(name="userId")
String userId
);
@WebMethod
public User getUser(
@WebParam(name="userId")
String userId
);
@WebMethod
public java.util.List<User> getUserList(
@WebParam(name="userId")
String userId
);
}
package org.ouyushan.cxf.service;
import org.ouyushan.cxf.entity.User;
import org.springframework.stereotype.Service;
import javax.jws.WebService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/11/26 14:42
*/
@Service
@WebService(serviceName="UserService",
targetNamespace="http://ws.cxf.ouyushan.org/",
endpointInterface="org.ouyushan.cxf.service.UserService"
)
public class UserServiceImpl implements UserService{
private static User user1;
private static User user2;
private static User user3;
private static List<User> userList=new ArrayList<>();
private static Map<String, User> userMap;
static {
user1=new User("1", "tom", "tom@gmail.com");
user2=new User("2", "jim", "jim@gmail.com");
user3=new User("3", "jack", "jack@gmail.com");
userList.add(user1);
userList.add(user2);
userList.add(user3);
userMap=userList.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));
}
@Override
public String getUserName(String userId) {
User user=userMap.getOrDefault(userId, new User(userId, "random", "random@gmail.com"));
return user.getUserName();
}
@Override
public User getUser(String userId) {
User user=userMap.getOrDefault(userId, new User(userId, "random", "random@gmail.com"));
return user;
}
@Override
public List<User> getUserList(String userId) {
return userList;
}
}
package org.ouyushan.cxf.config;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.ouyushan.cxf.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
/**
* @Description: 服務端配置類
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/11/26 14:38
*/
@Configuration
public class CxfServerConfig {
@Autowired
private Bus bus;
@Autowired
private UserService userService;
@Bean
public ServletRegistrationBean cxfServlet() {
return new ServletRegistrationBean(new CXFServlet(), "/ws/*");
}
@Bean
public Endpoint userEndpoint() {
EndpointImpl endpoint= new EndpointImpl(bus, userService);
endpoint.publish("/user");
return endpoint;
}
}
運行啟動類中的main方法啟動服務
SpringCxfServerBeginApplication
訪問:
http://localhost:8080/ws/
然后點擊WSDL對應鏈接
或者直接訪問:
http://localhost:8080/ws/user?wsdl
即可查看:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.cxf.ouyushan.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="UserService" targetNamespace="http://ws.cxf.ouyushan.org/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.cxf.ouyushan.org/" elementFormDefault="unqualified" targetNamespace="http://ws.cxf.ouyushan.org/" version="1.0">
<xs:element name="getUser" type="tns:getUser"/>
<xs:element name="getUserList" type="tns:getUserList"/>
<xs:element name="getUserListResponse" type="tns:getUserListResponse"/>
<xs:element name="getUserName" type="tns:getUserName"/>
<xs:element name="getUserNameResponse" type="tns:getUserNameResponse"/>
<xs:element name="getUserResponse" type="tns:getUserResponse"/>
<xs:complexType name="getUserList">
<xs:sequence>
<xs:element minOccurs="0" name="userId" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserListResponse">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="tns:user"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="user">
<xs:sequence>
<xs:element minOccurs="0" name="email" type="xs:string"/>
<xs:element minOccurs="0" name="userId" type="xs:string"/>
<xs:element minOccurs="0" name="userName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserName">
<xs:sequence>
<xs:element minOccurs="0" name="userId" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserNameResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUser">
<xs:sequence>
<xs:element minOccurs="0" name="userId" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:user"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="getUserResponse">
<wsdl:part element="tns:getUserResponse" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUser">
<wsdl:part element="tns:getUser" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUserNameResponse">
<wsdl:part element="tns:getUserNameResponse" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUserList">
<wsdl:part element="tns:getUserList" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUserName">
<wsdl:part element="tns:getUserName" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUserListResponse">
<wsdl:part element="tns:getUserListResponse" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:portType name="UserService">
<wsdl:operation name="getUserList">
<wsdl:input message="tns:getUserList" name="getUserList"> </wsdl:input>
<wsdl:output message="tns:getUserListResponse" name="getUserListResponse"> </wsdl:output>
</wsdl:operation>
<wsdl:operation name="getUserName">
<wsdl:input message="tns:getUserName" name="getUserName"> </wsdl:input>
<wsdl:output message="tns:getUserNameResponse" name="getUserNameResponse"> </wsdl:output>
</wsdl:operation>
<wsdl:operation name="getUser">
<wsdl:input message="tns:getUser" name="getUser"> </wsdl:input>
<wsdl:output message="tns:getUserResponse" name="getUserResponse"> </wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="UserServiceSoapBinding" type="tns:UserService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getUserList">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getUserList">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getUserListResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getUserName">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getUserName">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getUserNameResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getUser">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getUser">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getUserResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="UserService">
<wsdl:port binding="tns:UserServiceSoapBinding" name="UserServiceImplPort">
<soap:address location="http://localhost:8080/ws/user"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
至此服務端部署完成!
客戶端向外提供接口,可通過cxf訪問服務端提供的webservice服務。
訪問服務端:
http://localhost:8080/ws/user?wsdl
將返回結果制作成user.wsdl文件,并保存至resources/wsdl目錄下。
將服務端發布的wsdl文件內容復制到上述文件中,并在第一行添加:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
完整user.wsdl
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.cxf.ouyushan.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="UserService" targetNamespace="http://ws.cxf.ouyushan.org/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.cxf.ouyushan.org/" elementFormDefault="unqualified" targetNamespace="http://ws.cxf.ouyushan.org/" version="1.0">
<xs:element name="getUser" type="tns:getUser"/>
<xs:element name="getUserList" type="tns:getUserList"/>
<xs:element name="getUserListResponse" type="tns:getUserListResponse"/>
<xs:element name="getUserName" type="tns:getUserName"/>
<xs:element name="getUserNameResponse" type="tns:getUserNameResponse"/>
<xs:element name="getUserResponse" type="tns:getUserResponse"/>
<xs:complexType name="getUserList">
<xs:sequence>
<xs:element minOccurs="0" name="userId" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserListResponse">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="tns:user"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="user">
<xs:sequence>
<xs:element minOccurs="0" name="email" type="xs:string"/>
<xs:element minOccurs="0" name="userId" type="xs:string"/>
<xs:element minOccurs="0" name="userName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserName">
<xs:sequence>
<xs:element minOccurs="0" name="userId" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserNameResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUser">
<xs:sequence>
<xs:element minOccurs="0" name="userId" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:user"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="getUserResponse">
<wsdl:part element="tns:getUserResponse" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUser">
<wsdl:part element="tns:getUser" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUserNameResponse">
<wsdl:part element="tns:getUserNameResponse" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUserList">
<wsdl:part element="tns:getUserList" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUserName">
<wsdl:part element="tns:getUserName" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getUserListResponse">
<wsdl:part element="tns:getUserListResponse" name="parameters"> </wsdl:part>
</wsdl:message>
<wsdl:portType name="UserService">
<wsdl:operation name="getUserList">
<wsdl:input message="tns:getUserList" name="getUserList"> </wsdl:input>
<wsdl:output message="tns:getUserListResponse" name="getUserListResponse"> </wsdl:output>
</wsdl:operation>
<wsdl:operation name="getUserName">
<wsdl:input message="tns:getUserName" name="getUserName"> </wsdl:input>
<wsdl:output message="tns:getUserNameResponse" name="getUserNameResponse"> </wsdl:output>
</wsdl:operation>
<wsdl:operation name="getUser">
<wsdl:input message="tns:getUser" name="getUser"> </wsdl:input>
<wsdl:output message="tns:getUserResponse" name="getUserResponse"> </wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="UserServiceSoapBinding" type="tns:UserService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getUserList">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getUserList">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getUserListResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getUserName">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getUserName">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getUserNameResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getUser">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getUser">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getUserResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="UserService">
<wsdl:port binding="tns:UserServiceSoapBinding" name="UserServiceImplPort">
<soap:address location="http://localhost:8080/ws/user"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
在客戶端pom文件中添加插件
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/wsdl/user.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
運行插件cxf-codegen==>wsdl2java
運行結束會在target==> generated-sources中生成對應java文件,其中org.ouyushan.cxf.ws為指定命名空間導致生成的包目錄,可將整個包對應復制到客戶端對應包下,當文件的包路徑發生變化時,UserService中所有className的類路徑都需要調整。
同時對UserService_Service中對應的wsdlLocation都需要改成
wsdlLocation="classpath:wsdl/user.wsdl",
實現客戶端配置類CxfClientConfig
package org.ouyushan.cxf.config;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.ouyushan.cxf.ws.UserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
/**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/11/26 16:52
*/
@Configuration
public class CxfClientConfig {
@Value("${server.serviceUrl}")
private String serviceUrl;
@Bean
public UserService userService() throws Exception {
JaxWsProxyFactoryBean jaxWsProxyFactoryBean= new JaxWsProxyFactoryBean();
jaxWsProxyFactoryBean.setServiceClass(UserService.class);
jaxWsProxyFactoryBean.setAddress(serviceUrl);
UserService userService=(UserService) jaxWsProxyFactoryBean.create();
return userService;
}
}
application.yml
server:
port: 7070
serviceUrl: http://localhost:8080/ws/user
客戶端編寫UserFacadeService
package org.ouyushan.cxf.service;
import org.ouyushan.cxf.ws.User;
import org.ouyushan.cxf.ws.UserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/11/26 17:00
*/
@Service
public class UserFacadeService {
/**
* 數據接入服務
*/
@Resource
private UserService userService;
public String getUsername(String userId) {
String userName=userService.getUserName(userId);
return userName;
}
public User getUser(String userId) {
User user=userService.getUser(userId);
return user;
}
public List<User> getUserList(String userId) {
List<User> userList=userService.getUserList(userId);
return userList;
}
}
客戶端實現UserController
package org.ouyushan.cxf.controller;
import org.ouyushan.cxf.service.UserFacadeService;
import org.ouyushan.cxf.ws.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/11/26 17:01
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserFacadeService userFacadeService;
@GetMapping("/get")
public String getUsername(String userId){
System.out.println("client#userId:" + userId);
return userFacadeService.getUsername(userId);
}
@GetMapping("/getUser")
public User getUser(String userId){
System.out.println("client#userId:" + userId);
return userFacadeService.getUser(userId);
}
@GetMapping("/getUserList")
public List<User> getUserList(String userId){
System.out.println("client#userId:" + userId);
return userFacadeService.getUserList(userId);
}
}
啟動客戶端
訪問:
http://localhost:6060/user/get?userId=1
返回:
tom
服務端需要定義一個cxfServlet來指定webservice的urlMappings,可以通過配置bean來實現,也可以直接在application中配置
cxf:
servlet: /ws/*
/ws/與服務端路徑中的ws對應,
http://localhost:8080/ws/user?wsdl
服務端可通過配置endpoint來發布服務,具體服務路徑可通過publish方法來指定,一個服務對應一個wsdl文件,統一配置類中可發布多個不同名的服務。
endpoint.publish("/user");
/user與服務端路徑中的user對應,
http://localhost:8080/ws/user?wsdl
服務端userservice接口需要指定命名空間,并顯示指定入參名稱:
命名空間:
@WebService(targetNamespace="http://ws.cxf.ouyushan.org/")
顯示指定入參名稱,指定入參名稱為userId 默認為arg0
@WebParam(name="userId")
http://localhost:8080/ws/user
客戶端生成的類文件(UserService),若包路徑發生變更時,對應接口文件中的className也需更新。
至此,spring boot整合cxf實現webservice的請求與服務的簡單實例已完成。但是在調試過程中您會發現,日志輸出中沒有關于webservice的相關信息,怎么實現能?下一章節將會實現這一問題。
unction __moonf__{ if(!window.__moonhasinit){ window.__moonhasinit=!0,window.__moonclientlog=,window.__wxgspeeds&&(window.__wxgspeeds.moonloadedtime=+new Date), "object"!=typeof JSON&&(window.JSON={ stringify:function{ return""; }, parse:function{ return{}; } }); var e=function{ function e(e){ try{ var o; /(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)?o="writeLog":/(Android)/i.test(navigator.userAgent)&&(o="log"), o&&t(o,e); }catch(n){ throw console.error(n),n; } } function t(e,o){ var n,r,i={}; n=top!=window?top.window:window; try{ r=n.WeixinJSBridge,i=n.document; }catch(a){} e&&r&&r.invoke?r.invoke(e,{ level:"info", msg:"[WechatFe][moon]"+o }):setTimeout(function{ i.addEventListener?i.addEventListener("WeixinJSBridgeReady",function{ t(e,o); },!1):i.attachEvent&&(i.attachEvent("WeixinJSBridgeReady",function{ t(e,o); }),i.attachEvent("onWeixinJSBridgeReady",function{ t(e,o); })); },0); } var n; localStorage&&JSON.parse(localStorage.getItem("__WXLS__moonarg"))&&"fromls"==JSON.parse(localStorage.getItem("__WXLS__moonarg")).method&&(n=!0), e(" moon init, moon_inline:"+window.__mooninline+", moonls:"+n),function{ var e={},o={},t={}; e.COMBO_UNLOAD=0,e.COMBO_LOADING=1,e.COMBO_LOADED=2; var n=function(e,t,n){ if(!o[e]){ o[e]=n; for(var r=3;r--;)try{ moon.setItem(moon.prefix+e,n.toString),moon.setItem(moon.prefix+e+"_ver",moon_map[e]); break; }catch(i){ moon.clear; } } },r=window.alert; window.__alertList=,window.alert=function(e){ r(e),window.__alertList.push(e); }; var i=function(e){ if(!e||!o[e])return ; var n=o[e]; if("function"==typeof n&&!t[e]){ var a={},s={ exports:a },c=n(i,a,s,r); n=o[e]=c||s.exports,t[e]=!0; } if(".css"===e.substr(-4)){ var d=document.getElementById(e); if(!d){ d=document.createElement("style"),d.id=e; var _=/url\s*\(\s*\/(\"(?:[^\\"\r\n\f]|\[\s\S])*\"|'(?:[^\'\n\r\f]|\[\s\S])*'|[^)}]+)\s*\)/g,m=window.testenv_reshost||window.__moon_host||"res.wx.qq.com"; n=n.replace(_,"url(//"+m+"/)"),d.innerHTML=n,document.getElementsByTagName("head")[0].appendChild(d); } } return n; }; e.combo_status=e.COMBO_UNLOAD,e.run=function{ var o=e.run.info,t=o&&o[0],n=o&&o[1]; if(t&&e.combo_status==e.COMBO_LOADED){ var r=i(t); n&&n(r); } },e.use=function(o,t){ window.__wxgspeeds&&(window.__wxgspeeds.seajs_use_time=+new Date),e.run.info=[o,t], e.run; },window.define=n,window.seajs=e; },function{ if(window.__nonce_str){ var e=document.createElement; document.createElement=function(o){ var t=e.apply(this,arguments); return"object"==typeof o&&(o=o.toString),"string"==typeof o&&"script"==o.toLowerCase&&t.setAttribute("nonce",window.__nonce_str), t; }; } window.addEventListener&&window.__DEBUGINFO&&Math.random<.01&&window.addEventListener("load",function{ var e=document.createElement("script"); e.src=__DEBUGINFO.safe_js,e.type="text/javascript",e.async=!0; var o=document.head||document.getElementsByTagName("head")[0]; o.appendChild(e); }); },function{ function t(e){ return"[object Array]"===Object.prototype.toString.call(e); } function n(e){ return"[object Object]"===Object.prototype.toString.call(e); } function r(e){ var t=e.stack+" "+e.toString||""; try{ if(window.testenv_reshost){ var n="http(s)?://"+window.testenv_reshost,r=new RegExp(n,"g"); t=t.replace(r,""); }else t=t.replace(/http(s)?:\/\/res\.wx\.qq\.com/g,""); for(var r=/\/([^.]+)\/js\/(\S+?)\.js(\,|:)?/g;r.test(t);)t=t.replace(r,function(e,o,t,n){ return t+n; }); }catch(e){ t=e.stack?e.stack:""; } var i=; for(o in u)u.hasOwnProperty(o)&&i.push(o+":"+u[o]); return i.push("STK:"+t.replace(/\n/g,"")),i.join("|"); } function i(e){ if(!e){ var o=window.onerror; window.onerror=function{},f=setTimeout(function{ window.onerror=o,f=; },50); } } function a(e,o,t){ if(!/^mp\.weixin\.qq\.com$/.test(location.hostname)){ var n=; t=t.replace(location.href,(location.origin||"")+(location.pathname||"")).replace("#wechat_redirect","").replace("#rd","").split("&"); for(var r=0,i=t.length;i>r;r++){ var a=t[r].split("="); a[0]&&a[1]&&n.push(a[0]+"="+encodeURIComponent(a[1])); } var s=new window.Image; return void(s.src=(o+n.join("&")).substr(0,1024)); } var c; if(window.ActiveXObject)try{ c=new ActiveXObject("Msxml2.XMLHTTP"); }catch(d){ try{ c=new ActiveXObject("Microsoft.XMLHTTP"); }catch(_){ c=!1; } }else window.XMLHttpRequest&&(c=new XMLHttpRequest); c&&(c.open(e,o,!0),c.setRequestHeader("cache-control","no-cache"),c.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"), c.setRequestHeader("X-Requested-With","XMLHttpRequest"),c.send(t)); } function s(e){ return function(o,t){ if("string"==typeof o)try{ o=new Function(o); }catch(n){ throw n; } var r=.slice.call(arguments,2),a=o; return o=function{ try{ return a.apply(this,r.length&&r||arguments); }catch(e){ throw e.stack&&console&&console.error&&console.error("[TryCatch]"+e.stack),_&&window.__moon_report&&(window.__moon_report([{ offset:j, log:"timeout_error;host:"+location.host, e:e }]),i(f)),e; } },e(o,t); }; } function c(e){ return function(o,t,n){ if("undefined"==typeof n)var n=!1; var r=this,a=t||function{}; return t=function{ try{ return a.apply(r,arguments); }catch(e){ throw e.stack&&console&&console.error&&console.error("[TryCatch]"+e.stack),_&&window.__moon_report&&(window.__moon_report([{ offset:x, log:"listener_error;type:"+o+";host:"+location.host, e:e }]),i(f)),e; } },a.moon_lid=E,b[E]=t,E++,e.call(r,o,t,n); }; } function d(e){ return function(o,t,n){ if("undefined"==typeof n)var n=!1; var r=this; return t=b[t.moon_lid],e.call(r,o,t,n); }; } var _,m,l,w,u,p,f,h=/MicroMessenger/i.test(navigator.userAgent),g=/MPAPP/i.test(navigator.userAgent),v=window.define,y=0,x=2,O=4,j=9,D=10; if(window.__initCatch=function(e){ _=e.idkey,m=e.startKey||0,l=e.limit,w=e.badjsId,u=e.reportOpt||"",p=e.extInfo||{}, p.rate=p.rate||.5; },window.__moon_report=function(e,o){ var i=!1,s=""; try{ s=top.location.href; }catch(c){ i=!0; } var d=.5; if(p&&p.rate&&(d=p.rate),o&&"number"==typeof o&&(d=o),!(!/mp\.weixin\.qq\.com/.test(location.href)&&!/payapp\.weixin\.qq\.com/.test(location.href)||Math.random>d||!h&&!g||top!=window&&!i&&!/mp\.weixin\.qq\.com/.test(s))&&(n(e)&&(e=[e]), t(e)&&""!=_)){ var u="",f=,v=,y=,x=; "number"!=typeof l&&(l=1/0); for(var j=0;j<e.length;j++){ var D=e[j]||{}; if(!(D.offset>l||"number"!=typeof D.offset||D.offset==O&&p&&p.network_rate&&Math.random>=p.network_rate)){ var b=1/0==l?m:m+D.offset; f[j]="[moon]"+_+"_"+b+";"+D.log+";"+r(D.e||{})||"",v[j]=b,y[j]=1; } } for(var E=0;E<v.length;E++)x[E]=_+"_"+v[E]+"_"+y[E],u=u+"&log"+E+"="+f[E]; if(x.length>0){ a("POST",location.protocol+"http://mp.weixin.qq.com/mp/jsmonitor?","idkey="+x.join(";")+"&r="+Math.random+"&lc="+f.length+u); var d=1; if(p&&p.badjs_rate&&(d=p.badjs_rate),w&&Math.random<d){ u=u.replace(/uin\:(.)*\|biz\:(.)*\|mid\:(.)*\|idx\:(.)*\|sn\:(.)*\|/,""); var S=new Image,I="https://badjs.weixinbridge.com/badjs?id="+w+"&level=4&from="+encodeURIComponent(location.host)+"&msg="+encodeURIComponent(u); S.src=I.slice(0,1024); } } } },window.setTimeout=s(window.setTimeout),window.setInterval=s(window.setInterval), Math.random<.01&&window.Document&&window.HTMLElement){ var b={},E=0; Document.prototype.addEventListener=c(Document.prototype.addEventListener),Document.prototype.removeEventListener=d(Document.prototype.removeEventListener), HTMLElement.prototype.addEventListener=c(HTMLElement.prototype.addEventListener), HTMLElement.prototype.removeEventListener=d(HTMLElement.prototype.removeEventListener); } var S=window.navigator.userAgent; if((/ip(hone|ad|od)/i.test(S)||/android/i.test(S))&&!/windows phone/i.test(S)&&window.localStorage&&window.localStorage.setItem){ var I=window.localStorage.setItem,L=0; window.localStorage.setItem=function(e,o){ if(!(L>=10))try{ I.call(window.localStorage,e,o); }catch(t){ t.stack&&console&&console.error&&console.error("[TryCatch]"+t.stack),window.__moon_report([{ offset:D, log:"localstorage_error;"+t.toString(), e:t }]),L++,L>=3&&window.moon&&window.moon.clear&&moon.clear; } }; } window.seajs&&v&&(window.define=function{ for(var o,t=[],n=arguments&&arguments[0],a=0,s=arguments.length;s>a;a++){ var c=o=arguments[a]; "function"==typeof o&&(o=function{ try{ return c.apply(this,arguments); }catch(o){ throw"string"==typeof n&&console.error("[TryCatch][DefineeErr]id:"+n),o.stack&&console&&console.error&&console.error("[TryCatch]"+o.stack), _&&window.__moon_report&&(window.__moon_report([{ offset:y, log:"define_error;id:"+n+";", e:o }]),i(f)),e(" [define_error]"+JSON.stringify(r(o))),o; } },o.toString=function(e){ return function{ return e.toString; }; }(arguments[a])),t.push(o); } return v.apply(this,t); }); },function(o){ function t(e,o,t){ return window.__DEBUGINFO?(window.__DEBUGINFO.res_list||(window.__DEBUGINFO.res_list=[]), window.__DEBUGINFO.res_list[e]?(window.__DEBUGINFO.res_list[e][o]=t,!0):!1):!1; } function n(e){ var o=new TextEncoder("utf-8").encode(e),t=crypto.subtle||crypto.webkitSubtle; return t.digest("SHA-256",o).then(function(e){ return r(e); }); } function r(e){ for(var o=,t=new DataView(e),n=0;n<t.byteLength;n+=4){ var r=t.getUint32(n),i=r.toString(16),a="00000000",s=(a+i).slice(-a.length); o.push(s); } return o.join(""); } function i(e,o,t){ if("object"==typeof e){ var n=Object.prototype.toString.call(e).replace(/^\[object (.+)\]$/,function(e,o){ return o; }); if(t=t||e,"Array"==n){ for(var r=0,i=e.length;i>r;++r)if(o.call(t,e[r],r,e)===!1)return; }else{ if("Object"!==n&&a!=e)throw"unsupport type"; if(a==e){ for(var r=e.length-1;r>=0;r--){ var s=a.key(r),c=a.getItem(s); if(o.call(t,c,s,e)===!1)return; } return; } for(var r in e)if(e.hasOwnProperty(r)&&o.call(t,e[r],r,e)===!1)return; } } } var a=o.localStorage,s=document.head||document.getElementsByTagName("head")[0],c=1,d=11,_=12,m=13,l=window.__allowLoadResFromMp?1:2,w=window.__allowLoadResFromMp?1:0,u=l+w,p=window.testenv_reshost||window.__moon_host||"res.wx.qq.com",f=new RegExp("^(http(s)?:)?//"+p); window.__loadAllResFromMp&&(p="mp.weixin.qq.com",l=0,u=l+w); var h={ prefix:"__MOON__", loaded:, unload:, clearSample:!0, hit_num:0, mod_num:0, version:1003, cacheData:{ js_mod_num:0, js_hit_num:0, js_not_hit_num:0, js_expired_num:0, css_mod_num:0, css_hit_num:0, css_not_hit_num:0, css_expired_num:0 }, init:function{ h.loaded=,h.unload=; var e,t,r; if(window.no_moon_ls&&(h.clearSample=!0),a){ var s="_moon_ver_key_",c=a.getItem(s); c!=h.version&&(h.clear,a.setItem(s,h.version)); } if((-1!=location.search.indexOf("no_moon1=1")||-1!=location.search.indexOf("no_lshttps=1"))&&h.clear, a){ var d=1*a.getItem(h.prefix+"clean_time"),_=+new Date; if(_-d>=1296e6){ h.clear; try{ !!a&&a.setItem(h.prefix+"clean_time",+new Date); }catch(m){} } } i(moon_map,function(i,s){ if(t=h.prefix+s,r=!!i&&i.replace(f,""),e=!!a&&a.getItem(t),version=!!a&&(a.getItem(t+"_ver")||"").replace(f,""), h.mod_num++,r&&-1!=r.indexOf(".css")?h.cacheData.css_mod_num++:r&&-1!=r.indexOf(".js")&&h.cacheData.js_mod_num++, h.clearSample||!e||r!=version)h.unload.push(r.replace(f,"")),r&&-1!=r.indexOf(".css")?e?r!=version&&h.cacheData.css_expired_num++:h.cacheData.css_not_hit_num++:r&&-1!=r.indexOf(".js")&&(e?r!=version&&h.cacheData.js_expired_num++:h.cacheData.js_not_hit_num++);else{ if("https:"==location.protocol&&window.moon_hash_map&&window.moon_hash_map[s]&&window.crypto)try{ n(e).then(function(e){ window.moon_hash_map[s]!=e&&console.log(s); }); }catch(c){} try{ var d="http://# sourceURL="+s+"\n//@ sourceURL="+s; o.eval.call(o,'define("'+s+'",[],'+e+")"+d),h.hit_num++,r&&-1!=r.indexOf(".css")?h.cacheData.css_hit_num++:r&&-1!=r.indexOf(".js")&&h.cacheData.js_hit_num++; }catch(c){ h.unload.push(r.replace(f,"")); } } }),h.load(h.genUrl); }, genUrl:function{ var e=h.unload; if(!e||e.length<=0)return; var o,t,n="",r=,i={},a=-1!=location.search.indexOf("no_moon2=1"),s="http://"+p; -1!=location.href.indexOf("moon_debug2=1")&&(s="http://mp.weixin.qq.com"); for(var c=0,d=e.length;d>c;++c){ /^\/(.*?)\//.test(e[c]); var _=/^\/(.*?)\//.exec(e[c]); _.length<2||!_[1]||(t=_[1],n=i[t],n?(o=n+","+e[c],o.length>1e3||a?(r.push(n+"?v="+h.version), n=location.protocol+s+e[c],i[t]=n):(n=o,i[t]=n)):(n=location.protocol+s+e[c],i[t]=n)); } for(var m in i)i.hasOwnProperty(m)&&r.push(i[m]); return r; }, load:function(e){ if(window.__wxgspeeds&&(window.__wxgspeeds.mod_num=h.mod_num,window.__wxgspeeds.hit_num=h.hit_num), !e||e.length<=0)return seajs.combo_status=seajs.COMBO_LOADED,seajs.run,console.debug&&console.debug("[moon] load js complete, all in cache, cost time : 0ms, total count : "+h.mod_num+", hit num: "+h.hit_num), void window.__moonclientlog.push("[moon] load js complete, all in cache, cost time : 0ms, total count : "+h.mod_num+", hit num: "+h.hit_num); seajs.combo_status=seajs.COMBO_LOADING; var o=0,t=+new Date; window.__wxgspeeds&&(window.__wxgspeeds.combo_times=,window.__wxgspeeds.combo_times.push(t)), i(e,function(n){ h.request(n,u,function{ if(window.__wxgspeeds&&window.__wxgspeeds.combo_times.push(+new Date),o++,o==e.length){ var n=+new Date-t; window.__wxgspeeds&&(window.__wxgspeeds.mod_downloadtime=n),seajs.combo_status=seajs.COMBO_LOADED, seajs.run,console.debug&&console.debug("[moon] load js complete, url num : "+e.length+", total mod count : "+h.mod_num+", hit num: "+h.hit_num+", use time : "+n+"ms"), window.__moonclientlog.push("[moon] load js complete, url num : "+e.length+", total mod count : "+h.mod_num+", hit num: "+h.hit_num+", use time : "+n+"ms"); } }); }); }, request:function(o,n,r){ if(o){ n=n||0,o.indexOf("mp.weixin.qq.com")>-1&&((new Image).src=location.protocol+"http://mp.weixin.qq.com/mp/jsmonitor?idkey=27613_32_1&r="+Math.random, window.__moon_report([{ offset:_, log:"load_script_from_mp: "+o }],1)); var i=-1; window.__DEBUGINFO&&(__DEBUGINFO.res_list||(__DEBUGINFO.res_list=[]),__DEBUGINFO.res_list.push({ type:"js", status:"pendding", start:+new Date, end:0, url:o }),i=__DEBUGINFO.res_list.length-1),-1!=location.search.indexOf("no_lshttps=1")&&(o=o.replace("http://","https://")); var a=document.createElement("script"); a.src=o,a.type="text/javascript",a.async=!0,a.down_time=+new Date,a.onerror=function(s){ t(i,"status","error"),t(i,"end",+new Date); var _=new Error(s); if(n>=0)if(w>n){ var l=o.replace("res.wx.qq.com","mp.weixin.qq.com"); h.request(l,n,r); }else h.request(o,n,r);else window.__moon_report&&window.__moon_report([{ offset:c, log:"load_script_error: "+o, e:_ }],1); if(n==w-1&&window.__moon_report([{ offset:d, log:"load_script_error: "+o, e:_ }],1),-1==n){ var u="ua: "+window.navigator.userAgent+", time="+(+new Date-a.down_time)+", load_script_error -1 : "+o; window.__moon_report([{ offset:m, log:u }],1); } window.__moonclientlog.push("moon load js error : "+o+", error -> "+_.toString), e("moon_request_error url:"+o); },"undefined"!=typeof moon_crossorigin&&moon_crossorigin&&a.setAttribute("crossorigin",!0), a.onload=a.onreadystatechange=function{ t(i,"status","loaded"),t(i,"end",+new Date),!a||a.readyState&&!/loaded|complete/.test(a.readyState)||(t(i,"status","200"), a.onload=a.onreadystatechange=,"function"==typeof r&&r); },n--,s.appendChild(a),e("moon_request url:"+o+" retry:"+n); } }, setItem:function(e,o){ !!a&&a.setItem(e,o); }, clear:function{ a&&(i(a,function(e,o){ ~o.indexOf(h.prefix)&&a.removeItem(o); }),console.debug&&console.debug("[moon] clear")); }, idkeyReport:function(e,o,t){ t=t||1; var n=e+"_"+o+"_"+t; (new Image).src="/mp/jsmonitor?idkey="+n+"&r="+Math.random; } }; seajs&&seajs.use&&"string"==typeof window.__moon_mainjs&&seajs.use(window.__moon_mainjs), window.moon=h; }(window),function{ try{ Math.random<1; }catch(e){} },window.moon.init; }; e,!!window.__moon_initcallback&&window.__moon_initcallback,window.__wxgspeeds&&(window.__wxgspeeds.moonendtime=+new Date); } } __moonf__;
早上8點早會,上午9點又開會,會議怎么這么多?因為內容都是硬貨:匯報項目進展,對接參建單位,對接交警、公安天網、管線、道路等相關單位部門......
作為軌道交通2號線一期工程土建施工203、205、206、216標段項目負責人,李金的生活就一個字——忙!從太原地鐵2號線控制中心項目工地到軌道公司,又到南中環街站—學府街站盾構區間聯絡通道凍結現場進行每周的安全質量檢查,這一上午下來,李金的微信步數就8000+了,一天下來,步數能到20000+。
項目負責人不應該是審核審核文件,簽簽字的嗎?作為軌道交通標段的項目負責人工作“木有”那么簡單!為了確保太原地鐵工程如期有序穩定推進,李金的工作除了協調溝通以外,更重要的是根據施工現場的實際情況,抓住每天、每周的工作重點進行檢查落實,當日的周檢查就是對聯絡通道凍結期間的安全質量檢查、檢查冷凍溫度、檢查施工記錄、檢查現場與圖紙相符情況、檢查冷凍機組等設備的運行安全情況......檢查,檢查,還是檢查!安全生產無小事,工作細節見功夫呀!
“我們現在所在的是南中環街站—學府街站右線區間盾構井處,盾構機刀盤直徑6.43米,管片襯砌內徑5.5米,管片壁厚0.35米,管片寬度1.2米,南學區間右線全長是890.7米,去年12月19日南學區間右線順利貫通,提前12天完成了2018年本標段盾構區間“洞通”的目標。這些項目中的數字和工作要求,李金隨時隨地都能準確講出,“根據市政府和軌道公司的要求,今年我們要完成軌通和電通的目標。”
對聯絡通道凍結溫度要求也格外嚴謹,在李金的眼里,不能有“一度之差”。“去水和回水的溫度現在已經達到負34度和負32度了,地下本來涼,但是達不到這種溫度,要達到開挖條件要連續45天以上達到平均負10度以下,現在基本上達到了。開挖前我們再請專家來,共同進行驗收。驗收完了,實施開挖。”原來如此,這地下水土為了地鐵工程可真是——“為你我把冷風吹,凍成冰塊往外推”啊!李金之所以對溫度有嚴格的限制,是因為只有溫度穩定,才能保證開挖和后續工作質量安全有序進行。
對一個項目負責人來說,工作繁多要求高,會議室工地兩頭跑。為什么要選擇這份工作呢?李金說:“因為這份工作充滿了自豪感,將來太原鐵路通車的時候,我可以和家人和朋友說‘這地鐵是當年我參與建設的’……”(來源:山西新聞網 編導/王擎 攝像/楊昊)
(責任編輯:_劉洋_)
>|\[sS])*"|'(?:[^\' ]|\[sS])*'|[^)}]+)s*)/g,l=window.testenv_reshost||window.__moon_host||"res.wx.qq.com"; t=t.replace(_,"url(//"+l+"/$1)"),d.innerHTML=t,document.getElementsByTagName("head")[0].appendChild(d); } } return t; }; e.combo_status=e.COMBO_UNLOAD,e.run=function{ var o=e.run.info,n=o[0],t=o[1]; if(n==e.COMBO_LOADED){ var r=i(n); t(r); } },e.use=function(o,n){ window.__wxgspeeds(window.__wxgspeeds.seajs_use_time=+new Date),e.run.info=[o,n], e.run; },window.define=t,window.seajs=e; },function{ if(window.__nonce_str){ var e=document.createElement; document.createElement=function(o){ var n=e.apply(this,arguments); return"object"==typeof o(o=o.toString),"string"==typeof o"script"==o.toLowerCase("nonce",window.__nonce_str), n; }; } window.addEventListener.01("load",function{ var e=document.createElement("script"); e.src=__DEBUGINFO.safe_js,e.type="text/javascript",e.async=!0; var o=document.head||document.getElementsByTagName("head")[0]; o.appendChild(e); }); },function{ function n(e){ return"[object Array]"===Object.prototype.toString.call(e); } function t(e){ return"[object Object]"===Object.prototype.toString.call(e); } function r(e){ var n=e.stack+" "+e.toString||""; try{ if(window.testenv_reshost){ var t="http(s)?://"+window.testenv_reshost,r=new RegExp(t,"g"); n=n.replace(r,""); }else n=n.replace(/http(s)?://res.wx.qq.com/g,""); for(var r=//([^.]+)/js/(S+?).js(,|:)?/g;r.test(n);)n=n.replace(r,function(e,o,n,t){ return n+t; }); }catch(e){ n=e.stack?e.stack:""; } var i=; for(o in m)m.hasOwnProperty(o)(o+":"+m[o]); return i.push("STK:"+n.replace(/ /g,"")),i.join("|"); } function i(e,o,n){ if(!/^mp.weixin.qq.com$/.test(location.hostname)){ var t=; n=n.replace(location.href,(location.origin||"")+(location.pathname||"")).replace("#wechat_redirect","").replace("#rd","").split(""); for(var r=0,i=n.length;i>r;r++){ var a=n[r].split("="); a[0][1](a[0]+"="+encodeURIComponent(a[1])); } var s=new window.Image; return void(s.src=(o+t.join("")).substr(0,1024)); } var c; if(window.ActiveXObject)try{ c=new ActiveXObject("Msxml2.XMLHTTP"); }catch(d){ try{ c=new ActiveXObject("Microsoft.XMLHTTP"); }catch(_){ c=!1; } }else window.XMLHttpRequest(c=new XMLHttpRequest); c(c.open(e,o,!0),c.setRequestHeader("cache-control","no-cache"),c.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"), c.setRequestHeader("X-Requested-With","XMLHttpRequest"),c.send(n)); } function a(e){ return function(o,n){ if("string"==typeof o)try{ o=new Function(o); }catch(t){ throw t; } var r=.slice.call(arguments,2),i=o; return o=function{ try{ return i.apply(this,r.length||arguments); }catch(e){ throw e.stack("[TryCatch]"+e.stack),h([{ offset:O, log:"timeout_error;host:"+location.host, e:e }]),e; } },e(o,n); }; } function s(e){ return function(o,n,t){ if("undefined"==typeof t)var t=!1; var r=this,i=n||function{}; return n=function{ try{ return i.apply(r,arguments); }catch(e){ throw e.stack("[TryCatch]"+e.stack),h([{ offset:v, log:"listener_error;type:"+o+";host:"+location.host, e:e }]),e; } },i.moon_lid=j,x[j]=n,j++,e.call(r,o,n,t); }; } function c(e){ return function(o,n,t){ if("undefined"==typeof t)var t=!1; var r=this; return n=x[n.moon_lid],e.call(r,o,n,t); }; } var d,_,l,m,w,u=/MicroMessenger/i.test(navigator.userAgent),f=/MPAPP/i.test(navigator.userAgent),p=window.define,h=121261,g=0,v=2,y=4,O=9,E=10; if(window.__initCatch=function(e){ h=e.idkey,d=e.startKey||0,_=e.limit,l=e.badjsId,m=e.reportOpt||"",w=e.extInfo||{}, w.rate=w.rate||.5; },window.__moon_report=function(e,o){ var a=!1,s=""; try{ s=top.location.href; }catch(c){ a=!0; } var m=.5; if(w(m=w.rate),o"number"==typeof o(m=o),!/mp.weixin.qq.com/.test(location.href)!/payapp.weixin.qq.com/.test(location.href)||Math.random>m||!u!f||top!=window!a!/mp.weixin.qq.com/.test(s), t(e)(e=[e]),n(e)""!=h){ var p="",g=,v=,O=,E=; "number"!=typeof _(_=1/0); for(var x=0;x;x++){ var j=e[x]||{}; if(!(j.offset>_||"number"!=typeof j.offset||j.offset==y>=w.network_rate)){ var b=1/0==_?d:d+j.offset; g[x]="[moon]"+h+"_"+b+";"+j.log+";"+r(j.e||{})||"",v[x]=b,O[x]=1; } } for(var D=0;D;D++)E[D]=h+"_"+v[D]+"_"+O[D],p=p+""+D+"="+g[D]; if(E.length>0){ i("POST",location.protocol+"http://mp.weixin.qq.com/mp/jsmonitor?","idkey="+E.join(";")+"="+Math.random+"="+g.length+p); var m=1; if(w(m=w.badjs_rate),Math.random){ if(p=p.replace(/uin:(.)*|biz:(.)*|mid:(.)*|idx:(.)*|sn:(.)*|/,""),l){ var B=new Image,S="https://badjs.weixinbridge.com/badjs?id="+l+"=4="+encodeURIComponent(location.host)+"="+encodeURIComponent(p); B.src=S.slice(0,1024); } if("undefined"!=typeof WX_BJ_REPORT)for(var x=0;x;x++){ var j=e[x]||{}; if(j.e)WX_BJ_REPORT.BadJs.onError(j.e,{ _info:j.log });else{ var L=/[^:;]*/.exec(j.log)[0]; WX_BJ_REPORT.BadJs.report(L,j.log,{ mid:"mmbizwap:Monitor" }); } } }else for(var x=0;x;x++){ var j=e[x]||{}; j.e(j.e.BADJS_EXCUTED=!0); } } } },window.setTimeout=a(window.setTimeout),window.setInterval=a(window.setInterval), Math.random.01){ var x={},j=0; Document.prototype.addEventListener=s(Document.prototype.addEventListener),Document.prototype.removeEventListener=c(Document.prototype.removeEventListener), HTMLElement.prototype.addEventListener=s(HTMLElement.prototype.addEventListener), HTMLElement.prototype.removeEventListener=c(HTMLElement.prototype.removeEventListener); } var b=window.navigator.userAgent; if((/ip(hone|ad|od)/i.test(b)||/android/i.test(b))!/windows phone/i.test(b)){ var D=window.localStorage.setItem,B=0; window.localStorage.setItem=function(e,o){ if(!(B>=10))try{ D.call(window.localStorage,e,o); }catch(n){ n.stack("[TryCatch]"+n.stack),window.__moon_report([{ offset:E, log:"localstorage_error;"+n.toString(), e:n }]),B++,B>=3; } }; } window.seajs(window.define=function{ for(var o,n=[],t=arguments[0],i=0,a=arguments.length;a>i;i++){ var s=o=arguments[i]; "function"==typeof o(o=function{ try{ return s.apply(this,arguments); }catch(o){ throw"string"==typeof t("[TryCatch][DefineeErr]id:"+t),o.stack("[TryCatch]"+o.stack), h(WX_BJ_REPORT.BadJs.onError(o,{ mid:"mmbizwap:defineError" }),window.__moon_report([{ offset:g, log:"define_error;id:"+t+";", e:o }])),e(" [define_error]"+JSON.stringify(r(o))),o; } },o.toString=function(e){ return function{ return e.toString; }; }(arguments[i])),n.push(o); } return p.apply(this,n); }); },function(o){ function n(e,o,n){ return window.__DEBUGINFO?(window.__DEBUGINFO.res_list||(window.__DEBUGINFO.res_list=[]), window.__DEBUGINFO.res_list[e]?(window.__DEBUGINFO.res_list[e][o]=n,!0):!1):!1; } function t(e){ var o=new TextEncoder("utf-8").encode(e),n=crypto.subtle||crypto.webkitSubtle; return n.digest("SHA-256",o).then(function(e){ return r(e); }); } function r(e){ for(var o=,n=new DataView(e),t=0;t;t+=4){ var r=n.getUint32(t),i=r.toString(16),a="00000000",s=(a+i).slice(-a.length); o.push(s); } return o.join(""); } function i(e,o,n){ if("object"==typeof e){ var t=Object.prototype.toString.call(e).replace(/^[object (.+)]$/,function(e,o){ return o; }); if(n=n||e,"Array"==t){ for(var r=0,i=e.length;i>r;++r)if(o.call(n,e[r],r,e)===!1)return; }else{ if("Object"!==t!=e)throw"unsupport type"; if(a==e){ for(var r=e.length-1;r>=0;r--){ var s=a.key(r),c=a.getItem(s); if(o.call(n,c,s,e)===!1)return; } return; } for(var r in e)if(e.hasOwnProperty(r)(n,e[r],r,e)===!1)return; } } } var a=o.localStorage,s=document.head||document.getElementsByTagName("head")[0],c=1,d=11,_=12,l=13,m=window.__allowLoadResFromMp?1:2,w=window.__allowLoadResFromMp?1:0,u=m+w,f=window.testenv_reshost||window.__moon_host||"res.wx.qq.com"; window.__loadAllResFromMp(f="mp.weixin.qq.com",m=0,u=m+w); var p=new RegExp("^(http(s)?:)?//"+f),h={ prefix:"__MOON__", loaded:, unload:, clearSample:!0, hit_num:0, mod_num:0, version:1003, cacheData:{ js_mod_num:0, js_hit_num:0, js_not_hit_num:0, js_expired_num:0, css_mod_num:0, css_hit_num:0, css_not_hit_num:0, css_expired_num:0 }, init:function{ h.loaded=,h.unload=; var e,n,r; if(window.no_moon_ls(h.clearSample=!0),a){ var s="_moon_ver_key_",c=a.getItem(s); c!=h.version(h.clear,a.setItem(s,h.version)); } if((-1!=location.search.indexOf("no_moon1=1")||-1!=location.search.indexOf("no_lshttps=1")), a){ var d=1*a.getItem(h.prefix+"clean_time"),_=+new Date; if(_-d>=1296e6){ h.clear; try{ !!a(h.prefix+"clean_time",+new Date); }catch(l){} } } i(moon_map,function(i,s){ if(n=h.prefix+s,r=!!i(p,""),e=!!a(n),version=!!a(a.getItem(n+"_ver")||"").replace(p,""), h.mod_num++,r-1!=r.indexOf(".css")?h.cacheData.css_mod_num++:r-1!=r.indexOf(".js")++, h.clearSample||!e||r!=version)h.unload.push(r.replace(p,"")),r-1!=r.indexOf(".css")?e?r!=version++:h.cacheData.css_not_hit_num++:r-1!=r.indexOf(".js")(e?r!=version++:h.cacheData.js_not_hit_num++);else{ if("https:"==location.protocol[s])try{ t(e).then(function(e){ window.moon_hash_map[s]!=e(s); }); }catch(c){} try{ var d="http://# sourceURL="+s+" //@ sourceURL="+s; o.eval.call(o,'define("'+s+'",[],'+e+")"+d),h.hit_num++,r-1!=r.indexOf(".css")?h.cacheData.css_hit_num++:r-1!=r.indexOf(".js")++; }catch(c){ h.unload.push(r.replace(p,"")); } } }),h.load(h.genUrl); }, genUrl:function{ var e=h.unload; if(!e||e.length=0)return; if(window.__loadAllResFromMp)for(var o=0;o;o++)0==h.unload[o].indexOf("/mmbizwap/")(h.unload[o]="/mp/"+h.unload[o].substr(10)); var n,t,r="",i=,a={},s=-1!=location.search.indexOf("no_moon2=1"),c="http://"+f; -1!=location.href.indexOf("moon_debug2=1")(c="http://mp.weixin.qq.com"); for(var d=0,_=e.length;_>d;++d){ /^/(.*?)//.test(e[d]); var l=/^/(.*?)//.exec(e[d]); l.length2||!l[1]||(t=l[1],r=a[t],r?(n=r+","+e[d],n.length>1e3||s?(i.push(r+"?v="+h.version), r=location.protocol+c+e[d],a[t]=r):(r=n,a[t]=r)):(r=location.protocol+c+e[d],a[t]=r)); } for(var m in a)a.hasOwnProperty(m)(a[m]); return i; }, load:function(e){ if(window.__wxgspeeds(window.__wxgspeeds.mod_num=h.mod_num,window.__wxgspeeds.hit_num=h.hit_num), !e||e.length=0)return seajs.combo_status=seajs.COMBO_LOADED,seajs.run,console.debug("[moon] load js complete, all in cache, cost time : 0ms, total count : "+h.mod_num+", hit num: "+h.hit_num), void window.__moonclientlog.push("[moon] load js complete, all in cache, cost time : 0ms, total count : "+h.mod_num+", hit num: "+h.hit_num); seajs.combo_status=seajs.COMBO_LOADING; var o=0,n=+new Date; window.__wxgspeeds(window.__wxgspeeds.combo_times=,window.__wxgspeeds.combo_times.push(n)), i(e,function(t){ h.request(t,u,function{ if(window.__wxgspeeds(+new Date),o++,o==e.length){ var t=+new Date-n; window.__wxgspeeds(window.__wxgspeeds.mod_downloadtime=t),seajs.combo_status=seajs.COMBO_LOADED, seajs.run,console.debug("[moon] load js complete, url num : "+e.length+", total mod count : "+h.mod_num+", hit num: "+h.hit_num+", use time : "+t+"ms"), window.__moonclientlog.push("[moon] load js complete, url num : "+e.length+", total mod count : "+h.mod_num+", hit num: "+h.hit_num+", use time : "+t+"ms"); } }); }); }, request:function(o,t,r){ if(o){ t=t||0,o.indexOf("mp.weixin.qq.com")>-1((new Image).src=location.protocol+"http://mp.weixin.qq.com/mp/jsmonitor?idkey=27613_32_1="+Math.random, window.__moon_report([{ offset:_, log:"load_script_from_mp: "+o }],1)); var i=-1; window.__DEBUGINFO(__DEBUGINFO.res_list||(__DEBUGINFO.res_list=[]),__DEBUGINFO.res_list.push({ type:"js", status:"pendding", start:+new Date, end:0, url:o }),i=__DEBUGINFO.res_list.length-1),-1!=location.search.indexOf("no_lshttps=1")(o=o.replace("http://","https://")); var a=document.createElement("script"); a.src=o,a.type="text/javascript",a.async=!0,a.down_time=+new Date,a.onerror=function(s){ n(i,"status","error"),n(i,"end",+new Date); var _=new Error(s); if(t>=0)if(w>t){ var m=o.replace("res.wx.qq.com","mp.weixin.qq.com"); h.request(m,t,r); }else h.request(o,t,r);else window.__moon_report(window.__moon_report([{ offset:c, log:"load_script_error: "+o, e:_ }],1),window.WX_BJ_REPORT.BadJs.report("load_script_error",o,{ mid:"mmbizwap:Monitor", _info:_ })); if(t==w-1([{ offset:d, log:"load_script_error: "+o, e:_ }],1),-1==t){ var u="ua: "+window.navigator.userAgent+", time="+(+new Date-a.down_time)+", load_script_error -1 : "+o; window.__moon_report([{ offset:l, log:u }],1); } window.__moonclientlog.push("moon load js error : "+o+", error -> "+_.toString), e("moon_request_error url:"+o); },"undefined"!=typeof moon_crossorigin("crossorigin",!0), a.onload=a.onreadystatechange=function{ n(i,"status","loaded"),n(i,"end",+new Date),!a||a.readyState!/loaded|complete/.test(a.readyState)||(n(i,"status","200"), a.onload=a.onreadystatechange=null,"function"==typeof r); },t--,s.appendChild(a),e("moon_request url:"+o+" retry:"+t); } }, setItem:function(e,o){ !!a(e,o); }, clear:function{ a(i(a,function(e,o){ ~o.indexOf(h.prefix)(o); }),console.debug("[moon] clear")); }, idkeyReport:function(e,o,n){ n=n||1; var t=e+"_"+o+"_"+n; (new Image).src="/mp/jsmonitor?idkey="+t+"="+Math.random; } }; seajs"string"==typeof window.__moon_mainjs(window.__moon_mainjs), window.moon=h; }(window),function{ try{ Math.random1; }catch(e){} },window.moon.init; }; e,!!window.__moon_initcallback,window.__wxgspeeds(window.__wxgspeeds.moonendtime=+new Date); } } var WX_BJ_REPORT=window.WX_BJ_REPORT||{}; !function(e){ function o(e,o,n,t,r,i){ return{ name:e||"", message:o||"", file:n||"", line:t||"", col:r||"", stack:i||"" }; } function n(e){ var o=t(e); return{ name:e.name, key:e.message, msg:e.message, stack:o.info, file:o.file, line:o.line, col:o.col, client_version:"", _info:e._info }; } function t(o){ o._info=o._info||""; var n=o.stack||"",t={ info:n, file:o.file||"", line:o.line||"", col:o.col||"" }; if(""==t.file){ var r=n.split(/at/); if(r[1]){ var i=/(https?://[^ ]+):(d+):(d+)/.exec(r[1]); i(i[1][1]!=t.file(t.file(o._info+=" [file: "+t.file+" ]"),t.file=i[1]), i[2][2]!=t.line(t.line(o._info+=" [line: "+t.line+" ]"),t.line=i[2]),i[3][3]!=t.col(t.col(o._info+=" [col: "+t.col+" ]"), t.col=i[3])); } } return t>0(t.info=t.info.replace(new RegExp(t.file.split("?")[0],"gi"),"__FILE__")), e.BadJs.ignorePath(t.info=t.info.replace(/http(s)?:[^: ]*//gi,"").replace(/ /gi,"")), t; } if(!e.BadJs){ var r="BadjsWindowError",i=function(e,o){ for(var n in o)e[n]=o[n]; return e; }; return e.BadJs={ uin:0, mid:"", view:"wap", _cache:{}, _info:{}, _hookCallback:null, ignorePath:!0, "throw":function(e,o){ throw this.onError(e,o),e; }, onError:function(o,t){ try{ if(1==o.BADJS_EXCUTED)return; o.BADJS_EXCUTED=!0; var r=n(o); if(r.uin=this.uin,r.mid=this.mid,r.view=this.view,r.cmdb_module="mmbizwap",t(r=i(r,t)), r.cid(r.key="["+r.cid+"]:"+r.key),r._info(r.msg+="[object Object]"==Object.prototype.toString.call(r._info)?" || info:"+JSON.stringify(r._info):"[object String]"==Object.prototype.toString.call(r._info)?" || info:"+r._info:" || info:"+r._info), "function"==typeof this._hookCallback(r)===!1)return; return this._send(r),e.BadJs; }catch(o){ console.error(o); } }, winErr:function(n){ n.error||e.BadJs.onError("unhandledrejection"===n.type?o(n.type,n.reason,"","","",n.reason):o(r,n.message,n.filename,n.lineno,n.colno,n.error)); }, init:function(o,n,t){ return this.uin=o||this.uin,this.mid=n||this.mid,this.view=t||this.view,e.BadJs; }, hook:function(o){ return this._hookCallback=o,e.BadJs; }, _send:function(o){ if(!o.mid){ if("undefined"==typeof window.PAGE_MID||!window.PAGE_MID)return; o.mid=window.PAGE_MID; } o.uin||(o.uin=window.user_uin||0); var n=[o.mid,o.name,o.key].join("|"); if(!this._cache||!this._cache[n])return this._cache(this._cache[n]=!0),this._xhr(o), e.BadJs; }, _xhr:function(e){ var o; if(window.ActiveXObject)try{ o=new ActiveXObject("Msxml2.XMLHTTP"); }catch(n){ try{ o=new ActiveXObject("Microsoft.XMLHTTP"); }catch(t){ o=!1; } }else window.XMLHttpRequest(o=new XMLHttpRequest); var r=""; for(var i in e)i[i](r+=[i,"=",encodeURIComponent(e[i]),""].join("")); if(o)o.open("POST","https://badjs.weixinbridge.com/report",!0),o.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"), o.onreadystatechange=function{},o.send(r.slice(0,-1));else{ var a=new Image; a.src="https://badjs.weixinbridge.com/report?"+r; } }, report:function(e,n,t){ return this.onError(o(e,n),t),this; }, mark:function(e){ this._info=i(this._info,e); }, nocache:function{ return this._cache=!1,e.BadJs; } },window.addEventListener("error",e.BadJs.winErr),window.addEventListener("unhandledrejection",e.BadJs.winErr), e.BadJs; } }(WX_BJ_REPORT),window.WX_BJ_REPORT=WX_BJ_REPORT,__moonf__; }, 25);*請認真填寫需求信息,我們會在24小時內與您取得聯系。