XJC
xjc
是 Java Architecture for XML Binding (JAXB) 的一部分,它是一个命令行工具,用于将 XML 架构(XML Schema)转换为 Java 类。以下是 xjc
工具的基本用法:
基本命令格式
1
| xjc [options] <schema file/URL/dir>
|
常用选项
-d <directory>
: 指定生成 Java 类的目标目录。
-p <package>
: 指定生成的 Java 类应该放在哪个包中。
-encoding <encoding>
: 指定源文件编码。
-extension
: 使用 JAXB XML 绑定扩展。
-verbose
: 输出详细的日志信息。
示例
假设你有一个名为 schema.xsd
的 XML Schema 文件,且当前目录下有 src
文件夹,你想将它转换为 Java 类,并将这些类放在 com.example
包中,你可以使用以下命令:
1
| xjc -d ./src -p com.example schema.xsd
|
这将在 ./src
目录下创建 com/example
目录,并将生成的 Java 类放在该目录中。
注意事项
- 在 JDK 8 中,
xjc
工具位于 jaxb-xjc
包中。如果你使用的是 JDK 9 或更高版本,xjc
工具可能不再包含在默认的 JDK 中,你需要单独下载 JAXB 实现。
- 确保你的环境变量
JAVA_HOME
正确设置,并且 bin
目录在 PATH
环境变量中。
- 如果你在 Windows 上运行
xjc
,可能需要运行 xjc.exe
而不是 xjc
。
验证安装
在命令行中运行以下命令可以验证 xjc
是否可用:
如果 xjc
已正确安装,这个命令将显示版本信息。
使用 xjc
时可能遇到的问题通常与 XML Schema 本身有关,例如不正确的格式或者 xjc
无法处理的某些复杂结构。在这种情况下,你可能需要检查 XML Schema 文件或者查阅更详细的 xjc
文档来解决问题。
Maven插件:jaxb2-maven-plugin:2.5.0
插件配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <executions> <execution> <id>xjc</id> <goals> <goal>xjc</goal> </goals> </execution> </executions> <configuration> <sources> <source>src/main/resources/xsd</source> </sources> <outputDirectory>${project.basedir}/src/main/java</outputDirectory> <packageName>com.example.model</packageName> <clearOutputDir>false</clearOutputDir> </configuration> </plugin>
|
主要配置参数说明:
- sources: XSD 文件所在目录
- outputDirectory: 生成的 Java 类输出目录
- packageName: 生成的 Java 类的包名
- clearOutputDir: 是否在生成前清空输出目录
- encoding: 文件编码,默认 UTF-8
- extension: 是否启用 JAXB 扩展
- args: 传递给 XJC 的额外参数
常用的 goal:
- xjc: 从 XSD 生成 Java 类
- schemagen: 从 Java 类生成 XSD
- testXjc: 用于测试的 XJC goal
- testSchemagen: 用于测试的 schemagen goal
示例
XSD 文件 book.xsd:
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="book"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="author" type="xs:string"/> <xs:element name="price" type="xs:decimal"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
|
执行 mvn clean compile
后会生成对应的 Java 类。也可以使用 mvn jaxb:xjc
生成 Java 类
生成的绑定类使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| Book book = new Book(); book.setTitle("Java 编程思想"); book.setAuthor("Bruce Eckel"); book.setPrice(new BigDecimal("99.00"));
JAXBContext context = JAXBContext.newInstance(Book.class); Marshaller marshaller = context.createMarshaller(); marshaller.marshal(book, System.out);
Unmarshaller unmarshaller = context.createUnmarshaller(); Book unmarshalledBook = (Book) unmarshaller.unmarshal(new File("book.xml"));
|
高级配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <configuration> <arguments> <argument>-Xfluent-api</argument> </arguments> <bindingDirectory>src/main/resources/bindings</bindingDirectory> <episode>true</episode> <bindings> <binding> <includeSchema>**/*.xsd</includeSchema> <bindings>**/*.xjb</bindings> </binding> </bindings> </configuration>
|
常见问题处理:
- 如果生成的类有编码问题,检查 encoding 配置
- 如果需要自定义类型映射,使用 bindings 文件
- 如果要生成更简洁的 API,可以使用 -Xfluent-api 参数
- 如果有多个 XSD 之间有依赖关系,使用 episode 功能
最佳实践:
- 将 XSD 文件放在 src/main/resources/xsd 目录下
- 使用 clearOutputDir=false 避免覆盖手动修改的文件
- 对于大型项目建议使用 episode 功能提高编译效率
- 合理规划包名,避免与其他类冲突
- 添加必要的注释说明生成的代码用途
这样配置和使用 jaxb2-maven-plugin 可以方便地实现 XML 架构和 Java 类之间的映射。记得根据实际项目需求调整相关配置参数。
spring-boot-starter-web-services 通过xsd创建服务
依赖
1 2 3 4 5 6 7 8
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> </dependency>
|
schema文件
./src/main/java/resources/schema/users.xsd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.jeremytsai.com/users" targetNamespace="http://ws.jeremytsai.com/users" elementFormDefault="qualified">
<xs:element name="getUserRequest"> <xs:complexType> <xs:sequence> <xs:element name="id" type="xs:long"/> </xs:sequence> </xs:complexType> </xs:element>
<xs:element name="getUserResponse"> <xs:complexType> <xs:sequence> <xs:element name="user" type="tns:user"/> </xs:sequence> </xs:complexType> </xs:element>
<xs:complexType name="user"> <xs:sequence> <xs:element name="id" type="xs:long"/> <xs:element name="name" type="xs:string"/> <xs:element name="email" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>
|
配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.ws.config.annotation.EnableWs; import org.springframework.ws.config.annotation.WsConfigurerAdapter; import org.springframework.ws.transport.http.MessageDispatcherServlet; import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; import org.springframework.xml.xsd.SimpleXsdSchema; import org.springframework.xml.xsd.XsdSchema;
@EnableWs @Configuration public class WebServiceConfig extends WsConfigurerAdapter {
@Bean public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(ApplicationContext applicationContext) { MessageDispatcherServlet servlet = new MessageDispatcherServlet(); servlet.setApplicationContext(applicationContext); servlet.setTransformWsdlLocations(true); return new ServletRegistrationBean<>(servlet, "/ws/*"); }
@Bean(name = "users") public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema usersSchema) { DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); wsdl11Definition.setPortTypeName("UsersPort"); wsdl11Definition.setLocationUri("/ws"); wsdl11Definition.setTargetNamespace("http://ws.jeremytsai.com/users"); wsdl11Definition.setSchema(usersSchema); return wsdl11Definition; }
@Bean public XsdSchema usersSchema() { return new SimpleXsdSchema(new ClassPathResource("schema/users.xsd")); } }
|
enpoint类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import com.jeremytsai.ws.wsdl.users.GetUserRequest; import com.jeremytsai.ws.wsdl.users.GetUserResponse; import com.jeremytsai.ws.wsdl.users.User; import org.springframework.ws.server.endpoint.annotation.Endpoint; import org.springframework.ws.server.endpoint.annotation.PayloadRoot; import org.springframework.ws.server.endpoint.annotation.RequestPayload; import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
@Endpoint public class UserEndpoint {
private static final String NAMESPACE_URI = "http://ws.jeremytsai.com/users";
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getUserRequest") @ResponsePayload public GetUserResponse getUser(@RequestPayload GetUserRequest request) { GetUserResponse response = new GetUserResponse(); User user = new User(); user.setId(request.getId()); user.setName("张三"); user.setEmail("zhangsan@example.com"); response.setUser(user); return response; } }
|
使用插件从xsd生成java对象
插件配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <executions> <execution> <id>xjc</id> <goals> <goal>xjc</goal> </goals> </execution> </executions> <configuration> <sources> <source>src/main/resources/schema/users.xsd</source> </sources> <generateEpisode>false</generateEpisode> <outputDirectory>${project.basedir}/src/main/java</outputDirectory> <packageName>com.jeremytsai.ws.wsdl.users</packageName> <clearOutputDir>false</clearOutputDir> <extension>false</extension> </configuration> </plugin>
|
执行命令 mvn jaxb2:xjc
运行项目即可。
使用插件从pojo生成java对象
先创建各个pojo对象,使用对应的XML注解。这些对象同xsd生成的pojo。然后使用插件指定source为pojo的文件路径。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <executions> <execution> <id>xjc</id> <goals> <goal>xjc</goal> </goals> </execution> </executions> <configuration> <sources> <source>${project.basedir}/src/main/java/com/example/users</source> </sources>
<generateEpisode>false</generateEpisode> <outputDirectory>${project.basedir}/src/main/resources/xsd</outputDirectory> <clearOutputDir>false</clearOutputDir> </configuration> </plugin>
|
最后使用 mvn jaxb2:schemagen
生成即可。默认文件名为 schema1.xsd
,需要自己手动修改为对应的文件名。
JAX-WS (Java API for XML Web Services)
定义
JAX-WS 是一个 Java 编程语言 API,用于创建 Web 服务。它是 Java EE 平台的一部分,提供了一种标准化的方法来开发和部署 Web 服务。
目的
JAX-WS 旨在简化 Web 服务的开发,允许开发者专注于业务逻辑而不是底层的通信细节。
主要特性
- 支持 SOAP (Simple Object Access Protocol) 1.1 和 1.2
- 支持 WSDL (Web Services Description Language) 1.1
- 支持通过 HTTP 进行传输
- 提供了一套注解,简化了 Web 服务的开发
- 支持同步和异步的 Web 服务调用
关键注解
- @WebService:用于定义一个 Web 服务
- @WebMethod:用于暴露一个方法作为 Web 服务操作
- @WebParam:用于定制化方法参数的属性
- @WebResult:用于定制化方法返回值的属性
工作原理
JAX-WS 使用 JAXB (Java Architecture for XML Binding) 来处理 XML 和 Java 对象之间的映射。它可以自动生成 WSDL 文件,也可以从 WSDL 文件生成 Java 代码。
优势
- 标准化:作为 Java EE 的一部分,它提供了一个标准的 Web 服务开发方法
- 易用性:通过注解简化了 Web 服务的开发
- 灵活性:支持多种协议和编码
- 可移植性:JAX-WS 应用可以轻松地在不同的 Java EE 兼容的应用服务器之间移植
与 Spring 的关系
虽然 JAX-WS 不是 Spring 提供的功能,但 Spring 框架提供了对 JAX-WS 的集成支持。Spring 可以管理 JAX-WS 服务的生命周期,并可以将 Spring 的其他特性(如依赖注入)应用到 Web 服务中。