1. Web Service基础概念与Java EE定位
Web Service本质上是一种跨平台、跨语言的系统间通信方案。在Java EE(现Jakarta EE)体系中,它通过标准化协议实现不同技术栈应用的互操作。我最早接触Web Service是在2008年一个银行系统集成项目中,当时需要将核心业务系统暴露给第三方支付平台调用。
SOAP和REST是两种主流实现方式。SOAP基于XML协议栈,使用WSDL定义接口,适合需要严格契约的场景;REST则基于HTTP方法,采用轻量级的JSON数据格式,更适合移动互联网应用。Java EE对两者都提供了完整支持:
- JAX-WS:面向SOAP的Java API
- JAX-RS:面向REST的Java API
- JAXB:Java与XML数据绑定
- SAAJ:SOAP消息处理
实际项目选型时,如果对接方是传统企业系统(如SAP),通常选择SOAP;如果是移动端或前端调用,REST是更优解。
2. JAX-WS实现SOAP服务详解
2.1 服务端开发实战
通过@WebService注解即可快速创建服务端点:
@WebService(endpointInterface = "com.example.CalculatorService") public class CalculatorServiceImpl implements CalculatorService { @WebMethod public int add(int a, int b) { return a + b; } }部署时需要注意:
- 必须指定
endpointInterface以避免NoEndpoint异常 - 方法参数要使用简单类型或可序列化对象
- 建议使用
@WebResult(name="result")明确返回值名称
2.2 WSDL生成与解读
部署后访问?wsdl会生成如下关键部分:
<portType name="CalculatorService"> <operation name="add"> <input message="tns:addRequest"/> <output message="tns:addResponse"/> </operation> </portType> <binding name="CalculatorServiceImplPortBinding" type="tns:CalculatorService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> </binding>生产环境建议关闭WSDL自动生成,改为预先生成后静态部署,避免暴露内部结构。
3. JAX-RS构建RESTful服务
3.1 资源类设计模式
典型用户管理API实现:
@Path("/users") public class UserResource { @GET @Produces(MediaType.APPLICATION_JSON) public List<User> listUsers() { return userService.findAll(); } @POST @Consumes(MediaType.APPLICATION_JSON) public Response createUser(User user) { userService.save(user); return Response.status(201).build(); } }3.2 高级特性应用
- 异常处理:使用
ExceptionMapper统一转换业务异常
@Provider public class BusinessExceptionMapper implements ExceptionMapper<BusinessException> { @Override public Response toResponse(BusinessException ex) { return Response.status(400) .entity(new ErrorMessage(ex.getCode(), ex.getMessage())) .build(); } }- 超媒体控制:实现HATEOAS
@GET @Path("{id}") public User getUser(@PathParam("id") Long id) { User user = userService.findById(id); user.addLink( Link.fromUriBuilder(uriInfo.getAbsolutePathBuilder()).rel("self").build() ); return user; }4. 安全与性能优化
4.1 WS-Security配置
在sun-jaxws.xml中添加:
<bindings xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"> <wsam:Addressing> <wsam:NonAnonymousResponses/> </wsam:Addressing> <binding name="SecurityBinding"> <security:Security> <security:UsernameToken/> </security:Security> </binding> </bindings>4.2 REST性能调优
- 启用GZIP压缩:
@Provider public class GZipWriterInterceptor implements WriterInterceptor { @Override public void aroundWriteTo(WriterInterceptorContext context) throws IOException { context.getHeaders().add("Content-Encoding", "gzip"); context.setOutputStream(new GZIPOutputStream(context.getOutputStream())); context.proceed(); } }- 缓存控制策略:
@GET @CacheControl(maxAge = 3600) public Response getCatalog() { return Response.ok(catalog).build(); }5. 测试与调试技巧
5.1 SOAPUI测试要点
创建测试项目时注意:
- 设置WS-Security用户名令牌
- 添加WS-Addressing头
- 对响应做XPath断言
5.2 cURL调试命令集
常用调试命令示例:
# REST GET请求 curl -H "Accept: application/json" http://localhost:8080/api/users # 带认证的SOAP请求 curl -X POST -H "Content-Type: text/xml" \ -d @request.xml \ --user username:password \ http://localhost:8080/CalculatorService6. 企业级部署方案
6.1 容器适配方案
| 容器 | 配置要点 |
|---|---|
| WebLogic | 需要配置weblogic-webservices.xml |
| WebSphere | 使用admin console绑定策略集 |
| Tomcat | 添加jaxws-rt依赖 |
6.2 高可用设计
- 客户端负载均衡:
CalculatorService service = new CalculatorService(); CalculatorService port = service.getCalculatorServiceImplPort(); BindingProvider bp = (BindingProvider) port; bp.getRequestContext().put( BindingProvider.ENDPOINT_ADDRESS_PROPERTY, getNextEndpoint() );- 服务降级策略:
@WebService public class CalculatorFallback implements CalculatorService { @WebMethod public int add(int a, int b) { return 0; // 返回安全值 } }在服务熔断时自动切换到此实现类。