代码示例:基于JAX-WS和JAXB,其中http请求和响应的报文体都是xml数据

说明

基于JAX-WS编写了RESTful的web服务端点。
http请求和响应的报文体都是xml数据,服务端分别对应了用JAXB注解的请求和响应类。
只实现了服务端的代码示例
客户端使用了Postman

示例

要实现的目标:http请求和响应报文体的xml数据

http请求报文体的xml数据:

<?xml version="1.0" encoding="UTF-8"?>
<request>
    <reqtype>01</reqtype>
    <secret>test</secret>
    <body>0858032316</body>
</request>

http响应报文体的xml数据:

<?xml version='1.0' encoding='UTF-8'?>
<response>
    <body>15</body>
    <flag>1</flag>
</response>

代码实现

maven工程增加依赖

maven工程的pom.xml文件中增加如下依赖:

<dependency>
  <groupId>jakarta.xml.ws</groupId>
  <artifactId>jakarta.xml.ws-api</artifactId>
  <version>4.0.0</version>
</dependency>
<dependency>
  <groupId>com.sun.xml.ws</groupId>
  <artifactId>jaxws-rt</artifactId>
  <version>4.0.0</version>        
</dependency>

RESTful的web服务端点实现

package com.thb.server.register;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.ws.BindingType;
import jakarta.xml.ws.Provider;
import jakarta.xml.ws.WebServiceProvider;
import jakarta.xml.ws.http.HTTPBinding;
import jakarta.xml.ws.http.HTTPException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

@WebServiceProvider
@BindingType(value=HTTPBinding.HTTP_BINDING)
public class Register implements Provider<Source> {

    public Source invoke(Source source) {
        try {
            return process(source);
        } catch(Exception e) {
            e.printStackTrace();
            throw new HTTPException(500);
        }
    }

    private Source process(Source source) throws JAXBException { 
        // 传入的是xml数据时,此处source是com.sun.xml.ws.util.xml.StAXSource
        // 而不是javax.xml.transform.stax.StAXSource
        System.out.println(source.getClass().getName());

        // 参数中填写用JAXB注解的请求和响应类,它们分别对应请求的xml和响应的xml
        JAXBContext context = JAXBContext.newInstance(RegisterResponse.class,
                RegisterRequest.class);

        // 下面代码将收到的请求中的xml数据反序列化为Java对象
        // 创建一个Unmarshaller,反序列化使用
        Unmarshaller unmarshaller = context.createUnmarshaller();
        // 将接收到的xml数据反序列到java对象
        Object object = unmarshaller.unmarshal(source);
        // 打印出来反序列化后的Java对象的类型,是com.thb.server.register.RegisterRequest
        System.out.println(object.getClass().getName());
        // 将反序列化后的Java对象转换为RegisterRequest对象,RegisterRequest使用了JAXB注解
        RegisterRequest registerRequest = (RegisterRequest)object;
        // 将反序列化以后的Java对象的属性打印出来,看是否符合预期
        System.out.println("functionCode: " + registerRequest.getFunctionCode());
        System.out.println("enterpriseAccount: " + registerRequest.getEnterpriseAccount());
        System.out.println("secret: " + registerRequest.getSecret());

        // 下面代码将Java对象序列化为xml数据
        // 创建一个Marshaller,序列化使用
        Marshaller marshaller = context.createMarshaller();
        // 设置序列化后的xml的编码类型。此处不设置也可以
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        // 创建一个输出输出流
        ByteArrayOutputStream  outputStream = new ByteArrayOutputStream();
        // 创建响应的java对象,并设置对象的属性,该对象使用了JAXB注解
        RegisterResponse registerResponse = new RegisterResponse();
        registerResponse.setFlag(1);
        registerResponse.setEnterpriseId("15");
        // 将Java对象序列到输出流
        marshaller.marshal(registerResponse, outputStream);
        // 取输出流中的字节
        byte[] bytes = outputStream.toByteArray();
        // 构造输入流
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        // 用输入流构造StreamSource
        return new StreamSource(inputStream);
    }

}

http请求xml对应的java对象,使用了JAXB注解

package com.thb.server.register;

import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;

/**
 * 该类映射到http请求的xml
 * @author thb
 *
 */
// 使用了JAXB注解,映射到xml中的request元素
@XmlRootElement(name = "request")
public class RegisterRequest {

    private int functionCode;

    private String secret;

    private String enterpriseAccount;

    // 使用了JAXB注解,映射到xml中的reqtype元素
    @XmlElement(name="reqtype")
    public int getFunctionCode() {
        return this.functionCode;
    }

    // 此处的setter函数要有,否则从xml反序列到java对象的时候无法赋值
    public void setFunctionCode(int functionCode) {
        this.functionCode = functionCode;
    }

    // 使用了JAXB注解,映射到xml中的secret元素
    @XmlElement(name="secret")
    public String getSecret() {
        return this.secret;
    }

    // 此处的setter函数要有,否则从xml反序列到java对象的时候无法赋值
    public void setSecret(String secret) {
        this.secret = secret;
    }

    // 使用了JAXB注解,映射到xml中的body元素
    @XmlElement(name = "body")
    public String getEnterpriseAccount() {
        return this.enterpriseAccount;
    }

    // 此处的setter函数要有,否则从xml反序列到java对象的时候无法赋值
    public void setEnterpriseAccount(String enterpriseAccount) {
        this.enterpriseAccount = enterpriseAccount;
    }
}

http响应xml对应的java对象,使用了JAXB注解

package com.thb.server.register;

import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;

/**
 * 该类映射到http响应的xml
 * @author thb
 *
 */
//使用了JAXB注解,映射到xml中的response元素
@XmlRootElement(name = "response")
public class RegisterResponse {

    private int flag;

    private String enterpriseId;

    public RegisterResponse() {}

    //使用了JAXB注解,映射到xml中的flag元素
    @XmlElement(name = "flag")
    public int getFlag() {
        return this.flag;
    }

    public void setFlag(int flag) {
        this.flag = flag;
    }

    //使用了JAXB注解,映射到xml中的body元素
    @XmlElement(name = "body")
    public String getEnterpriseId() {
        return this.enterpriseId;
    }

    public void setEnterpriseId(String enterpriseId) {
        this.enterpriseId = enterpriseId;
    }

}

web应用的web.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="6.0" xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd">
    <description>power-restful</description>
    <display-name>power-restful</display-name>
    <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
        <description>The JAX-WS dispatcher servlet</description>
        <display-name>dispatcher</display-name>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/register/*
    
    
        60
    

sun-jaxws.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<endpoints
    xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
    version="2.0">

    <endpoint
        name="restful-register"
        implementation="com.thb.server.register.Register"
        url-pattern="/register/*" />
</endpoints>

web应用部署到tomcat的目录布局

D:\APACHE-TOMCAT-10.1.13\WEBAPPS\POWER-RESTFUL
├─META-INF
│      MANIFEST.MF
│      war-tracker
│      
└─WEB-INF
    │  sun-jaxws.xml
    │  web.xml
    │  
    ├─classes
    │  └─com
    │      └─thb
    │          └─server
    │              └─register
    │                      Register.class
    │                      RegisterRequest.class
    │                      RegisterResponse.class
    │                      
    └─lib
            angus-activation-1.0.0.jar
            angus-mail-1.0.0.jar
            FastInfoset-2.1.0.jar
            gmbal-api-only-4.0.3.jar
            ha-api-3.1.13.jar
            jakarta.activation-api-2.1.0.jar
            jakarta.annotation-api-2.1.1.jar
            jakarta.mail-api-2.1.0.jar
            jakarta.xml.bind-api-4.0.0.jar
            jakarta.xml.soap-api-3.0.0.jar
            jakarta.xml.ws-api-4.0.0.jar
            jaxb-core-4.0.0.jar
            jaxb-impl-4.0.0.jar
            jaxws-rt-4.0.0.jar
            log4j-api-2.20.0.jar
            log4j-core-2.20.0.jar
            management-api-3.2.3.jar
            mimepull-1.10.0.jar
            saaj-impl-3.0.0.jar
            stax-ex-2.1.0.jar
            stax2-api-4.2.1.jar
            streambuffer-2.1.0.jar
            woodstox-core-6.2.8.jar

用Postman发送请求、收到的响应

代码示例:基于JAX-WS和JAXB,其中http请求和响应的报文体都是xml数据_第1张图片

你可能感兴趣的:(http,xml,JAX-WS,JAXB)