1. 程式人生 > >二十九、Springboot整合Web services,構建SOAP服務

二十九、Springboot整合Web services,構建SOAP服務

(一)新增依賴

        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web-services</artifactId>
		</dependency>

		<dependency>
			<groupId>wsdl4j</groupId>
			<artifactId>wsdl4j</artifactId>
			<version>1.6.3</version>
		</dependency>

(二)建立SOAP服務端

1、編寫Schema檔案

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           targetNamespace="http://segmentfault.com/schemas"
           xmlns="http://segmentfault.com/schemas">
    <!--使用者物件:Id,Name, Age-->
    <xs:complexType name="User">
        <xs:sequence>
            <!--
            name:必須定義
            type:型別
            maxOccurs/minOccurs:都為1,表示必須有;maxOccurs為1,minOccurs為0,表示該物件是可選的
            -->
            <xs:element name="id" type="xs:string" maxOccurs="1" minOccurs="1"/>
            <xs:element name="name" type="xs:string" maxOccurs="1" minOccurs="1"/>
            <xs:element name="age" type="xs:int" maxOccurs="1" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="UserIdRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="userId" type="xs:string"/>
                <xs:element name="timeStamp" type="xs:long"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="UserResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="user" type="User"/>
                <xs:element name="timeStamp" type="xs:long"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

2、將其轉換成java檔案

3、建立倉儲

@Repository
public class UserRepository {
    private Map<String, User> cachedUsers = new HashMap<>();
    @PostConstruct
    public void init(){
        User user1 = createUser("1", "潘暢", 25);
        User user2 = createUser("2", "劉德華", 26);
        User user3 = createUser("3", "黃曉明", 27);
        /**
         * 知識點:
         */
        cachedUsers.put("1", user1);
        cachedUsers.put("2", user2);
        cachedUsers.put("3", user3);
    }
    private User createUser(String id, String name, Integer age){
        User user = new User();
        user.setId(id);
        user.setName(name);
        user.setAge(age);

        return user;
    }

    public User findById(String id){
        return cachedUsers.get(id);
    }
}

4、建立endpoint

/**
 * 使用者服務的Endpoint(端點)
 */
@Endpoint
public class UserServiceEndpoint {
    private UserRepository userRepository;
    @Autowired
    public UserServiceEndpoint(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * namespace = "http://segmentfault.com/schemas":同user.xsd檔案中的targetNamespace屬性
     * @ResponsePayload類似於@ResponseBody註解
     * @RequestPayload類似於@RequestBody註解
     */
    @PayloadRoot(namespace = "http://segmentfault.com/schemas", localPart = "UserIdRequest")
    @ResponsePayload
    public UserResponse getUser(@RequestPayload UserIdRequest userIdRequest){
        String userId = userIdRequest.getUserId();
        long timeStamp = userIdRequest.getTimeStamp();
        /**
         * JDK1.8出品:執行緒安全
         */
        Instant instant = Instant.ofEpochMilli(timeStamp);
        //轉換成本地時區
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());

        System.out.println("web service 使用者ID:" + userId + ",請求的時間:" + zonedDateTime);
        User user = userRepository.findById(userId);
        UserResponse userResponse = new UserResponse();
        userResponse.setUser(user);
        userResponse.setTimeStamp(Instant.now().toEpochMilli());
        return userResponse;
    }
}

5、建立Web services配置類

/**
 * web service 配置類
 */
@Configuration
public class WebServicesConfiguration extends WsConfigurerAdapter {
    /**
     *     設定訪問路徑:@Bean("my"),案例:http://localhost:8080/test/ws/my.wsdl,
     * 其中,wsdl是MessageDispatcherServlet中規定的結尾
     * @param userXsdSchema @Autowired自動裝配下方的userXsdSchema
     * @return Wsdl11Definition物件
     */
    @Bean("my")
    @Autowired
    public Wsdl11Definition userWsdl11Definition(XsdSchema userXsdSchema){
        DefaultWsdl11Definition defaultWsdl11Definition = new DefaultWsdl11Definition();

        defaultWsdl11Definition.setPortTypeName("UserServicePort");
        //設定訪問路徑:@Bean("my"),案例:http://localhost:8080/test/ws/my.wsdl
        defaultWsdl11Definition.setLocationUri("/ws");
        //user.xsd中的targetNamespace屬性
        defaultWsdl11Definition.setTargetNamespace("http://segmentfault.com/schemas");
        defaultWsdl11Definition.setSchema(userXsdSchema);

        return defaultWsdl11Definition;
    }

    /**
     * 註冊user.xsd(Schema檔案)對應的java物件
     */
    @Bean
    public XsdSchema userXsdSchema(){
        return new SimpleXsdSchema(new ClassPathResource("META-INF/schemas/user.xsd"));
    }
}

6、配置Web servicesfang訪問根路徑

spring:
  webservices:
    #自定義訪問路徑字首,比如這裡的訪問例項:http://localhost:8080/test/ws/my.wsdl
    path: /test

        到這裡,服務端就建立完畢了!

(三)建立SOAP客戶端

/**
 * Web Service 客戶端(Spring 實現)
 */
public class WebServicesClient {
    public static void main(String[] args) {
        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();

        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setClassesToBeBound(UserIdRequest.class, UserResponse.class, User.class);

        webServiceTemplate.setMarshaller(jaxb2Marshaller);
        webServiceTemplate.setUnmarshaller(jaxb2Marshaller);

        //構造 SOAP 請求
        UserIdRequest userIdRequest = new UserIdRequest();
        userIdRequest.setUserId("1");
        userIdRequest.setTimeStamp(Instant.now().toEpochMilli());

        /**
         * http://localhost:8080/test/ws/my:訪問請求地址
         * http://localhost:8080/test/ws/my.wsdl:這裡出現的是xml檔案內容
         */
        UserResponse userResponse = (UserResponse) webServiceTemplate.marshalSendAndReceive(
                "http://localhost:8080/test/ws/my", userIdRequest);

        System.out.println(userResponse);
    }
}