j. piggens
j. piggens

Reputation: 25

JAX-RS Jersey REST api call mapping

im trying to get my head around using Rest services in jersey/java. the link i am requesting is similar to

https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols=MSFT,FB,AAPL&apikey=demo note this is a demo link.

the JSON response is as follows:

{
    "Meta Data": {
        "1. Information": "Batch Stock Market Quotes",
        "2. Notes": "IEX Real-Time Price provided for free by IEX (https://iextrading.com/developer/).",
        "3. Time Zone": "US/Eastern"
    },
    "Stock Quotes": [
        {
            "1. symbol": "MSFT",
            "2. price": "87.8300",
            "3. volume": "18638820",
            "4. timestamp": "2018-01-10 16:00:00"
        },
        {
            "1. symbol": "FB",
            "2. price": "187.8100",
            "3. volume": "10515752",
            "4. timestamp": "2018-01-10 16:00:00"
        },
        {
            "1. symbol": "AAPL",
            "2. price": "174.2500",
            "3. volume": "23771860",
            "4. timestamp": "2018-01-10 16:00:00"
        }
    ]
}

My question is how do i properly map this in a java class? Here is what i've tried

StockREST.java

public class StockREST {
    private String symbol;
    private float price;
    private float volume;
    private String timestamp;

    public String getStockQuotes() {
        return StockQuotes;
    }

    public void setStockQuotes(String StockQuotes) {
        this.StockQuotes = StockQuotes;
    }
   private String StockQuotes;

    public String getSymbol() {
        return symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public float getVolume() {
        return volume;
    }

    public void setVolume(float volume) {
        this.volume = volume;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

     @Override
public String toString() {
    return "Symbol = " + symbol + " price, = "
            + price + ", volume = " + volume + ", timestamp = " + timestamp;
}


}

and

RESTclient.java

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;

/**
 *
 * @author Me
 */
public class RESTclient {
    public static void main(String[] args) {

    Client client = ClientBuilder.newClient();

StockREST exchange = client.target("https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols=MSFT&apikey=B1KLWMIAGSG0UWYD") 

                      .request(MediaType.APPLICATION_JSON)
                      .get(StockREST.class);


 String symbol = exchange.getSymbol();
float price = exchange.getPrice();
float volume = exchange.getVolume();
String timestamp = exchange.getTimestamp();


System.out.println(exchange);


client.close();
}
}

The SOUT message prints Symbol = null price, = 0.0, volume = 0.0, timestamp = null

ive tried with arrays/list but still confused. Thanks

EDIT

updated RESTClient.java

public class RESTclient {
    public static void main(String[] args) {

    Client client = ClientBuilder.newClient();

Response exchange = client.target("https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols=MSFT&apikey=B1KLWMIAGSG0UWYD") 

                      .request(MediaType.APPLICATION_JSON)
                      .get(Response.class);


// String symbol = exchange.getSymbol();
MetaData metaData = exchange.getMetaData();
List<StockQuote> stockQuotes = exchange.getStockQuotes();
//float price = exchange.getPrice();
//float volume = exchange.getVolume();
//String timestamp = exchange.getTimestamp();


System.out.println(exchange);


client.close();
}
}

Upvotes: 0

Views: 1259

Answers (1)

Mumrah81
Mumrah81

Reputation: 2054

First your returned object is not a StockREST but a composed object that you can call Response which will need to be mapped to a class Response.class

.get(StockREST.class);

become

.get(Response.class);

Then invalid java field name must be mapped to valid java field name

"1. symbol" must be mapped to something valid for java like "symbol"

Below are classes with mapping accurate for your case (getters and setters are omited)

@XmlRootElement
public class Response {
    @XmlAttribute(name = "Meta Data")
    private MetaData metaData;
    @XmlAttribute(name = "Stock Quotes")
    private List<StockQuote> stockQuotes;
}

public class MetaData {
    @XmlAttribute(name = "1. Information")
    private String information;
    @XmlAttribute(name = "2. Notes")
    private String notes;
    @XmlAttribute(name = "3. Time Zone")
    private String timeZone;
}

public class StockQuote {
    @XmlAttribute(name = "1. symbol")
    private String symbol;
    @XmlAttribute(name = "2. price")
    private float price;
    @XmlAttribute(name = "3. volume")
    private float volume;
    @XmlAttribute(name = "4. timestamp")
    private String timestamp;
}

EDIT:

Also you're requesting a secure url (https) so you need to provide a truststore containing trusted ssl certificate(s) to access your url

The following code bypass the certificate check which is BAD

public static void main(String[] args) {
     // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
            public X509Certificate[] getAcceptedIssuers(){return null;}
            public void checkClientTrusted(X509Certificate[] certs, String authType){}
            public void checkServerTrusted(X509Certificate[] certs, String authType){}
        }};

        // Install the all-trusting trust manager
        SSLContext sc = null;
        try {
            sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            System.out.println(e);
        }

        Client client = ClientBuilder.newBuilder().sslContext(sc).build();

        Response exchange = client.target("https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols=MSFT&apikey=B1KLWMIAGSG0UWYD") 

                              .request(MediaType.APPLICATION_JSON)
                              .get(Response.class);

        System.out.println(exchange.getMetaData());
        for (StockQuote sq : exchange.getStockQuotes()) {
            System.out.println(sq);
        }


        client.close();
    }

Homework done, enjoy

Upvotes: 1

Related Questions