API development with Jersey
Zaw Htut Win

Zaw Htut Win @zawhtutwin

About: Developer, Code Poet

Location:
Yangon
Joined:
Jun 4, 2021

API development with Jersey

Publish Date: May 23
0 0

Jersey ကို Rest API တွေ ကြားခံသုံးဖို့ အတွက် အသုံးများပါတယ်။ ကိုယ့် API ကနေ တခြား API တွေကို ကြားခံပေးဖို့ controller တွေဆောက်ဖို့ သုံးတာပါ။ Jersey project ကို စချင်ရင် အရင်ဆုံး https://start.spring.io/ ကို အရင်သွားပါ။ ဟုတ်ပါတယ်။ Spring.io က maven project ကိုလိုချင်လို့ပါ။

Image description

ပြီးရင်တော့ Dependency ထဲကို Jersey ကို ထည့်ပါ။
ပြီးရင် Generate ကိုနှိပ်ပြီး download လုပ်ပါ။

Image description

Extract လုပ်ထားတဲ့ zip file content တွေရှိတဲ့နေရာကို import လုပ်ပါ။ Existing Maven project ဆိုပြီးလုပ်ပါ။

Image description

ဒါမျိုးမြင်ရမယ်။

ဒါက project folder structure

Image description

pom.xml
အပြည့်အစုံကတော့ ဒါမျိုးပါ။ ဒီနေရာမှာ သတိထားပါ။ JDK 11 ကို သုံးထားပါတယ်။ maven.compiler.source က 11 ပါ။ စက်ထဲမှာ JDK 11 ရှိနေရပါမယ်။ Project Build Path မှာ JDK 11 ကိုထည့်ထားရပါမယ်။

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>weather-api</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <jersey.version>2.26</jersey.version>
    </properties>

    <dependencies>
        <!-- Jersey Server -->
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <!-- Grizzly HTTP Server for Jersey -->
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-grizzly2-http</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <!-- HK2 Dependency Injection -->
        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <!-- JSON support via Jackson -->
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <!-- JAX-RS API -->
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.1.1</version>
        </dependency>

        <!-- Logging (optional but useful) -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.36</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.39</version> 
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0.1</version>
        </dependency>       
    </dependencies>

    <build>
        <plugins>
            <!-- Maven Compiler Plugin for JDK 11 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Enter fullscreen mode Exit fullscreen mode

Main.java

package com.example.weather;

import java.io.IOException;
import java.net.URI;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

public class Main {
    // Base URI where the server will listen
    public static final String BASE_URI = "http://localhost:8080/api/";

    public static HttpServer startServer() {
        final ResourceConfig rc = new ResourceConfig();
        rc.register(WeatherResource.class).register(org.glassfish.jersey.jackson.JacksonFeature.class);
        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI),rc);
    }

    public static void main(String[] args) throws IOException {
        final HttpServer server = startServer();
        System.out.printf("Jersey app started at %s%nPress Ctrl+C to stop it...%n", BASE_URI);
    }
}

Enter fullscreen mode Exit fullscreen mode

ဒါကတော့ WeatherResource လို့ခေါ်တဲ့ Jersey API ပါ။ Open Street map နဲ့ geocoding လုပ်တယ်။(Yangon ဆို lat နဲ့ long ပြန်ရမယ်) အဲဒီက lat နဲ့‌ long ကို weather service ကိုထည့်ပေးလိုက်တာ

package com.example.weather;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.uri.UriComponent;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;


@Path("/weather")
public class WeatherResource {

    private final Client client = ClientBuilder.newClient();

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getWeatherByCity(@QueryParam("name") String city) {
        if (city == null || city.isBlank()) {
            return Response.status(Response.Status.BAD_REQUEST).entity("Missing city name").build();
        }

        String geoUrl = "https://nominatim.openstreetmap.org/search?q=" + 
                        UriComponent.encode(city, UriComponent.Type.QUERY_PARAM) +
                        "&format=json&limit=1";

        String geoJson = client.target(geoUrl)
                               .request()
                               .header("User-Agent", "Jersey Client")
                               .get(String.class);

        ObjectMapper mapper = new ObjectMapper();
        JsonNode geoArray = null;
        try {
            geoArray = mapper.readTree(geoJson);
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (!geoArray.isArray() || geoArray.isEmpty()) {
            return Response.status(Response.Status.NOT_FOUND).entity("City not found").build();
        }

        JsonNode location = geoArray.get(0);
        double lat = location.get("lat").asDouble();
        double lon = location.get("lon").asDouble();

        String weatherUrl = String.format(
            "https://api.open-meteo.com/v1/forecast?latitude=%f&longitude=%f&current=temperature_2m,wind_speed_10m",
            lat, lon
        );

        String weatherJson = client.target(weatherUrl)
                                   .request()
                                   .get(String.class);

        return Response.ok(weatherJson).build();
    }
}


Enter fullscreen mode Exit fullscreen mode

http://localhost:8080/api/weather?name=Yangon
ဆိုရင်

Image description

  • Jersey က JAX-RS ရဲ့ official implementation ဖြစ်ပါတယ်။ Standard ကျတဲ့ Restful service တွေကို သုံးချင်ရင် သူ့ကိုသုံးတာပါ။

  • Jersey ကို Run ဖို့ dependency နည်းနည်းပဲလိုပါတယ်။ Spring လိုမျိုး Abstraction အများကြီးလုပ်မထားဘူး။ Spring လို auto config တွေအများကြီး မလိုဘူး။ သေးပြီး မြန်ချင်ရင် Jersey ကို သုံးပါတယ်။

  • Jersey မှာ Build-in Async Response တွေ support ပေးထားပါတယ်။

  • တခြား Glassfish တို့ Payara တို့ Windfly တို့ အစရှိတဲ့ server တွေကို config လုပ်ရတာ Spring ထက်ပိုလွယ်ပါတယ်။

  • Jersey ကို သုံးရင် JAX-RS ကို လေ့လာပြီးသားဖြစ်သွားမှာပါ။

Comments 0 total

    Add comment