杰瑞科技汇

Java如何开发Web Services?

Of course! Let's dive deep into the world of web services in Java. This is a fundamental topic in modern enterprise Java development.

Java如何开发Web Services?-图1
(图片来源网络,侵删)

What is a Web Service?

At its core, a web service is a standardized way of integrating web-based applications using the internet's open protocols. It's a software system designed to support interoperable machine-to-machine interaction over a network.

Think of it as a contract between two applications:

  • The Service Provider: The application that offers the service (e.g., a weather service).
  • The Service Consumer (Client): The application that uses the service (e.g., a weather app on your phone).

They communicate over the web, typically using HTTP, and the messages are formatted in a standard way, most commonly XML or JSON.


The Two Main Architectural Styles for Web Services in Java

There are two dominant approaches to creating web services in Java, each with its own philosophy and use cases.

Java如何开发Web Services?-图2
(图片来源网络,侵删)
Feature SOAP (Simple Object Access Protocol) REST (Representational State Transfer)
Acronym Simple Object Access Protocol Representational State Transfer
Protocol A strict, standardized protocol. An architectural style, not a protocol.
Data Format Almost exclusively XML. Typically JSON, but can be XML, HTML, etc.
Standard Has an official standard (W3C). No official standard, governed by best practices (Roy Fielding's dissertation).
Contract Uses a formal contract defined in a WSDL (Web Services Description Language) file. The contract is often implicit (defined by the API itself), but can be documented with OpenAPI/Swagger.
Transport Primarily HTTP, but can also use SMTP, TCP, etc. Almost exclusively over HTTP/HTTPS.
Operations Uses standard operations defined by SOAP (e.g., SOAPAction). Uses standard HTTP methods (GET, POST, PUT, DELETE).
Security Built-in, robust security standards (WS-Security, WS-Policy). Security is handled through standard web mechanisms (HTTPS, OAuth, API Keys).
Tooling Excellent, mature tooling (e.g., wsimport in Java). Very popular tooling (e.g., OpenAPI/Swagger generators).
Complexity More complex to set up and configure. Simpler, more lightweight, and easier to work with.
Best For Enterprise environments, ACID transactions, high-security needs, interoperability with legacy systems. Public APIs, Mobile Backends, Microservices, Internet of Things (IoT).

Creating a SOAP Web Service in Java (The Classic Way)

The standard for creating SOAP services in Java is JAX-WS (Java API for XML Web Services). It's part of the Java EE (now Jakarta EE) specification.

Core Concepts:

  • @WebService: An annotation to mark a class as a web service endpoint implementation.
  • @WebMethod: An annotation to mark a public method as a web service operation.
  • wsimport: A command-line tool that comes with the JDK. It reads a WSDL file and generates the necessary Java client-side stubs and skeletons to consume the service.

Step-by-Step Example: A Simple Calculator Service

Step 1: Create the Service Endpoint Interface (SEI) or Implementation Class

You can start with an interface or just implement the logic directly. Let's do a class.

// src/main/java/com/example/Calculator.java
package com.example;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService marks this class as a web service endpoint.
@WebService
// @SOAPBinding specifies the style (DOCUMENT) and use (LITERAL).
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
public class Calculator {
    // @WebMethod marks this method as a web service operation.
    @WebMethod
    public int add(int a, int b) {
        return a + b;
    }
    @WebMethod
    public int subtract(int a, int b) {
        return a - b;
    }
}

Step 2: Create a Publisher Class

Java如何开发Web Services?-图3
(图片来源网络,侵删)

This class uses the JAX-WS API to publish your service on a specific URL and port.

// src/main/java/com/example/CalculatorPublisher.java
package com.example;
import javax.xml.ws.Endpoint;
public class CalculatorPublisher {
    public static void main(String[] args) {
        // The URL where the service will be published.
        String url = "http://localhost:9876/calculator";
        // Publish the service implementation.
        Endpoint.publish(url, new Calculator());
        System.out.println("Calculator service is published at: " + url);
    }
}

Step 3: Run the Publisher

Execute the CalculatorPublisher class. Your SOAP service is now live!

Step 4: Generate and Use the Client

Now, let's create a client to consume this service.

  1. Get the WSDL URL: Point your browser to http://localhost:9876/calculator?wsdl. You will see the WSDL (XML) file that describes your service.

  2. Generate Client Artifacts: Open a terminal and use the wsimport tool.

    # -keep: Keep the generated source files.
    # -p com.example.client: The package for the generated classes.
    wsimport -keep -p com.example.client http://localhost:9876/calculator?wsdl

    This will generate a bunch of Java files in the com.example.client package, including Calculator and CalculatorService.

  3. Write the Client Code

    // src/main/java/com/example/CalculatorClient.java
    package com.example;
    import com.example.client.Calculator; // This is the generated service interface
    import com.example.client.CalculatorService; // This is the generated service factory
    public class CalculatorClient {
        public static void main(String[] args) {
            // Create an instance of the service factory.
            CalculatorService service = new CalculatorService();
            // Get the port (the proxy) to invoke the web service operations.
            Calculator calculator = service.getCalculatorPort();
            // Call the operations.
            int sum = calculator.add(10, 5);
            int difference = calculator.subtract(10, 5);
            System.out.println("10 + 5 = " + sum);
            System.out.println("10 - 5 = " + difference);
        }
    }

Note: For production, you would use a proper web server like Apache Tomcat or JBoss/WildFly to host your JAX-WS service, not just a standalone Java application.


Creating a RESTful Web Service in Java (The Modern Way)

The standard for creating REST services in Java is JAX-RS (Java API for RESTful Web Services). The most popular implementation is Jersey, but others include RESTEasy (from Red Hat) and Apache CXF.

Core Concepts:

  • @Path: An annotation to define the base URI path for a resource class or method.
  • @GET, @POST, @PUT, @DELETE: Annotations to map HTTP methods to Java methods.
  • @Produces: Specifies the MIME media types that a resource method can produce and send back to the client (e.g., @Produces(MediaType.APPLICATION_JSON)).
  • @Consumes: Specifies the MIME media types that a resource method can accept from the client.
  • @PathParam, @QueryParam, @FormParam: Annotations to bind values from the request URI or form data to method parameters.

Step-by-Step Example: A RESTful Product API

Step 1: Add Dependencies

You need a JAX-RS implementation (Jersey) and a JSON library (like Jackson).

If you're using Maven, add this to your pom.xml:

<dependencies>
    <!-- JAX-RS API (for annotations) -->
    <dependency>
        <groupId>jakarta.platform</groupId>
        <artifactId>jakarta.jakartaee-api</artifactId>
        <version>10.0.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- Jersey Implementation (Servlet) -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>3.1.2</version>
    </dependency>
    <!-- Jackson for JSON support -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-binding</artifactId>
        <version>3.1.2</version>
    </dependency>
</dependencies>

Step 2: Create the Resource Class

// src/main/java/com/example/ProductResource.java
package com.example;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.*;
@Path("/products") // Base URI for all methods in this class
@Produces(MediaType.APPLICATION_JSON) // Default response type
public class ProductResource {
    // In-memory "database"
    private Map<Integer, Product> products = new HashMap<>();
    private int currentId = 1;
    public ProductResource() {
        // Seed with some data
        products.put(currentId, new Product(currentId++, "Laptop", 1200.00));
        products.put(currentId, new Product(currentId++, "Mouse", 25.00));
    }
    // GET /products
    @GET
    public List<Product> getAllProducts() {
        return new ArrayList<>(products.values());
    }
    // GET /products/{id}
    @GET
    @Path("/{id}")
    public Response getProductById(@PathParam("id") int id) {
        Product product = products.get(id);
        if (product == null) {
            // Return 404 Not Found if the product doesn't exist
            return Response.status(Response.Status.NOT_FOUND).build();
        }
        // Return 200 OK with the product
        return Response.ok(product).build();
    }
    // POST /products
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createProduct(Product product) {
        product.setId(currentId++);
        products.put(product.getId(), product);
        // Return 201 Created with the location of the new resource
        return Response.status(Response.Status.CREATED).entity(product).build();
    }
}

You'll also need a simple Product POJO (Plain Old Java Object):

// src/main/java/com/example/Product.java
package com.example;
public class Product {
    private int id;
    private String name;
    private double price;
    // Constructors, Getters, and Setters
    public Product() {}
    public Product(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
    // Getters and Setters...
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
}

Step 3: Configure the Application

You need to register your resource with the Jersey servlet.

// src/main/java/com/example/MyApplication.java
package com.example;
import org.glassfish.jersey.server.ResourceConfig;
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        // Register the resource class
        register(ProductResource.class);
    }
}

Step 4: Configure web.xml

Tell your web server (like Tomcat) to use Jersey to handle requests to your application.

<!-- src/main/webapp/WEB-INF/web.xml -->
<web-app 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_5_0.xsd"
         version="5.0">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jakarta.ws.rs.Application</param-name>
            <param-value>com.example.MyApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>
</web-app>

Step 5: Deploy and Test

  1. Deploy this application to a servlet container like Apache Tomcat.

  2. Use a tool like Postman or curl to test your API.

    • Get all products:
      curl http://localhost:8080/YourAppName/api/products
    • Get product with ID 1:
      curl http://localhost:8080/YourAppName/api/products/1
    • Create a new product:
      curl -X POST -H "Content-Type: application/json" -d '{"name":"Keyboard","price":75.00}' http://localhost:8080/YourAppName/api/products

Which One Should I Choose?

Choose SOAP if... Choose REST if...
✅ You need to formalize a strict contract between client and server. ✅ You need a simple, lightweight, and flexible API.
✅ You require high levels of security (WS-Security, WS-Policy). ✅ You are building a public API or a microservice architecture.
✅ You are working in a large enterprise with heterogeneous systems. ✅ You need to support multiple data formats like JSON and XML easily.
✅ You need to perform ACID transactions across services. ✅ You are building a mobile or single-page application (SPA) backend.
✅ Your network is unreliable, and you need built-in error handling and retries. ✅ You prioritize developer experience and ease of use.

In the current landscape, REST and JSON are the de facto standard for new web services due to their simplicity and performance. SOAP is still heavily used in enterprise environments, especially in financial, banking, and telecom sectors, where its strict contracts and security features are paramount.

分享:
扫描分享到社交APP
上一篇
下一篇