How to Call RESTful API Web Service in Servlet
In this article, I will introduce how to call RESTful API in servlet.
Introduction
In this article, I will introduce how to call RESTful API in servlet.
Background
Assume that we need to search and show the weather condition of the specified city. There are a lot of third web services on the internet. I am using Baidu Weather web service to demonstrate this. Now, let's get started with the following steps.
Using the Code
- Go to the website where you choose to use the web service, and register an account and get an apikey for you.
- Find and understand the API description. Take Baidu for example.
- API Address: http://apis.baidu.com/heweather/weather/free
- Request Method:
GET
- Request Parameter in Header:
Name
Type
Required
location
Description
Default Value
apikey
string
yes
header
APIkey from your web service provider for you
apikey
- Url Parameter:
Name
Type
Required
location
Description
Default Value
city
string
yes
urlParam
city name
beijing
- Result in Json:
"HeWeather data service 3.0": [ { "status": "ok", //status, "basic": { //basic info "city": "Beijing", //city name "cnty": "China", //country "id": "CN101010100", //city id "lat": "39.904000", //latitude of city "lon": "116.391000", //longitude of city "update": { //update time "loc": "2015-07-02 14:44", //locate time "utc": "2015-07-02 06:46" //UTC time } }, "now": { // the weather at this time "cond": { //weather condition "code": "100", //weather condition code "txt": "sunny day" //weather condiftion description }, ,...... //Omitted } ] }
- For the sake of test REST API easily. Please find or install some tools on your computer, such as restclient, fiddler and so on. If you are using Chrome or Firefox browser, you can also install REST client add-in. I installed Advanced REST Client on my Chrome browser.
- Launch the rest client. Please input API address and apikey like the below picture, and click Send button. You will get a json
string
result. - Launch http://www.jsonschema2pojo.org/ and copy the json string result and paste it in the page to generate the javabean classes. Then download the zip and unpack them to your project folder after you create a dynamic Web Project in Eclipse.
- When you open your project with Eclipse, you will see the following image:
- Create a new package for services such as com.BaiduWeather.Services. Here the proxy to call RESTfull API locate. Add a class named BaiduWeatherService.java and the code lines as below in it.
Notice:
- Before this, you should download the gson-2.8.0.jar from Gson Download at Maven Central, copy it to the folder WebContent/WEB-INF/lib/gson-2.8.0.jar and add it to Java Build Path.
- Remember to change the apiKey with yours.
package com.BaiduWeather.Services; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import com.BaiduWeather.Entities.Root; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; /** * baidu weather service */ public class BaiduWeatherService { private static final String apiKey="0ae09eed4f3c024451ads12d1gsgsg1sg";//change this with yours private static final String baseBaiduUrl= "http://apis.baidu.com/heweather/weather/free?city=";//The constant url should be //stored in config file public static Root getWeatherInfo(String cityName) { String jsonResult=getWeatherJsonString(cityName); Root weatherInfoObject=toEntity(jsonResult); return weatherInfoObject; } //Covert json string to class object private static Root toEntity(String jsonString) { try{ Gson gson = new GsonBuilder().create(); Root weatherInfo = gson.fromJson(jsonString, Root.class); return weatherInfo; } catch(JsonSyntaxException ex) { ex.printStackTrace(); return null; } } //Get the weather of the specific city private static String getWeatherJsonString(String cityName) throws RuntimeException{ //define a variable to store the weather api url and set beijing as it's default value String baiduUrl = baseBaiduUrl+"beijing"; //default value hard-coded 'beijing' //should be stored in config file try { if(cityName!=null && cityName!="") baiduUrl = baseBaiduUrl+URLEncoder.encode(cityName, "utf-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } StringBuilder strBuf = new StringBuilder(); HttpURLConnection conn=null; BufferedReader reader=null; try{ //Declare the connection to weather api url URL url = new URL(baiduUrl); conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept", "application/json"); conn.setRequestProperty("apikey",apiKey); if (conn.getResponseCode() != 200) { throw new RuntimeException("HTTP GET Request Failed with Error code : " + conn.getResponseCode()); } //Read the content from the defined connection //Using IO Stream with Buffer raise highly the efficiency of IO reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8")); String output = null; while ((output = reader.readLine()) != null) strBuf.append(output); }catch(MalformedURLException e) { e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } finally { if(reader!=null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if(conn!=null) { conn.disconnect(); } } return strBuf.toString(); } }
- Create a new package
com.BaiduWeather.Servlets
and a new class WeatherServlet.java under it. Add the following code lines in this Java file:package com.BaiduWeather.Servlets; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.BaiduWeather.Entities.HeWeatherDataService30; import com.BaiduWeather.Entities.Root; import com.BaiduWeather.Services.BaiduWeatherService; /** * Servlet implementation class WeatherServlet * * We can use 。jsp instead of servlet */ @WebServlet("/weather") public class WeatherServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public WeatherServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Get weather json info and convert it to object String city=request.getParameter("city"); Root wheatherInfoObject=BaiduWeatherService.getWeatherInfo(city); if(wheatherInfoObject!=null){ List<HeWeatherDataService30> weatherlist= wheatherInfoObject.getHeWeatherDataService30(); if(weatherlist!=null) { //output the weather content on web page. StringBuilder outputContent=new StringBuilder();//Unless the need of thread-safe, //Use StringBuilder not StringBuffer,because the latter takes more erformance overhead because of Synchronization //More cities can be store in a database or file,then load them into an array,then generators options of selection here outputContent.append("<!DOCTYPE html><html><head><meta charset=\"UTF-8\"> <title>Insert title here</title></head><body><form action=\"weather\" method=\"GET\"><select name=\"city\"><option value =\"beijing\">北京</option> <option value =\"shanghai\">上海</option><option value =\"xian\">西安</option> </select><input type=\"submit\" value=\"Submit\"></form>"); outputContent.append(weatherlist.get(0).getBasic().getCity()); outputContent.append("<br/>"); outputContent.append(weatherlist.get(0).getNow().getTmp()); outputContent.append("℃"); outputContent.append("<br/>"); outputContent.append(weatherlist.get(0).getNow().getCond().getTxt()); outputContent.append("<br/>"); outputContent.append(weatherlist.get(0).getNow().getWind().getDir()); outputContent.append("</body></html>"); response.setContentType("text/html; charset=utf-8"); response.getWriter().write(outputContent.toString()); } } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
- In WebContent/WEB-INF/web.xml, add the following configuration items.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>BaiduWeather</display-name> <welcome-file-list> <!-- <welcome-file>index.html</welcome-file> --> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> <welcome-file>weather</welcome-file> </welcome-file-list> <servlet> <!-- class name --> <servlet-name>WeatherServlet</servlet-name> <!-- package--> <servlet-class>com.BaiduWeather.Servlets.WeatherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>WeatherServlet</servlet-name> <!-- address --> <url-pattern>/BaiduWeather/weather</url-pattern> </servlet-mapping> </web-app>
- Run and debug this servlet, you should get weather information on an HTML page.
Thanks for reading!