前言
由于開始要搭建一個java + python的服務,java端提供數據庫增刪改查邏輯供python端調用牌芋,第一時間想到了用REST(Representational State Transfer)進行交互
最近這些年,REST已經成為web services和APIs的標準架構,很多APP的架構基本上是使用RESTful的形式了扁凛。
REST的六個特性:
- Client-Server:服務器端與客戶端分離。
- Stateless(無狀態(tài)):每次客戶端請求必需包含完整的信息闯传,換句話說绕沈,每一次請求都是獨立的。
- Cacheable(可緩存):服務器端必需指定哪些請求是可以緩存的泡躯。
- Layered System(分層結構):服務器端與客戶端通訊必需標準化祖娘,服務器的變更并不會影響客戶端。
- Uniform Interface(統(tǒng)一接口):客戶端與服務器端的通訊方法必需是統(tǒng)一的妹窖。
- Code on demand(按需執(zhí)行代碼纬朝?):服務器端可以在上下文中執(zhí)行代碼或者腳本?
以下就是我的簡單嘗試
正文
由于REST服務也是一個web服務骄呼,所以需要一個servlet容器共苛。
因為主邏輯還是在java端蜓萄,所以希望這個REST服務非常輕量嫉沽,選擇一個輕量級的servlet容器很有必要堂竟,神馬Tomcat出嘹、Resin就太重了税稼,所以鼎鼎大名的 jetty 容器就是非常好的選擇啦
容器選好了郎仆,就再考慮用什么RESTful框架實現咯丸升,由于在java6上已經有了一套RESTful的api狡耻,叫:JAX-RS (Java API for RESTful Web Services)岭皂,但JAX-RS 的具體實現由第三方提供爷绘,例如 Sun 的參考實現 Jersey土至、Apache 的 CXF 以及 JBoss 的 RESTEasy陶因。各項性能比較不錯的是Jersey和RESTEasy楷扬,各種百度google一番烘苹,最后任性的選擇了Jersey
工具都選好了镣衡,開始干正事了捆探,上代碼:
首先配置下maven依賴:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19.4</version>
</dependency>
<!-- 對象自動轉json -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.aggregate</groupId>
<artifactId>jetty-all-server</artifactId>
<version>8.2.0.v20160908</version>
</dependency>
再來寫java代碼:
/**
* Copyright (C) 2017 The RDT of Wireless R&D in MIG. All right reversed. <p/> Created by vellhe on
* 2017/7/7
*/
package com.tencent.awake.data.processing.service.rest;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.tencent.awake.data.processing.db.mybatis.dao.model.SubTaskInfoPo;
import com.tencent.awake.data.processing.db.mybatis.dao.model.TaskInfoPo;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Date;
/**
* @author vellhe@tencent.com
* @date 2017/7/7
* @description 提供REST接口
*/
@Path("/")
public class RestInterface {
/**
* 根據id查詢任務信息.
*
* @param id 任務id
* @return 任務信息
*/
@Path("/getTaskInfo/{id}") // 大括號里的是參數名,在函數位置使用@PathParam注解映射
@GET // 聲明這個接口必須GET訪問
@Produces(MediaType.APPLICATION_JSON) // 聲明這個接口將以json格式返回
public TaskInfoPo getTaskInfo(@PathParam("id") int id) {
TaskInfoPo taskInfoPo = new TaskInfoPo();
taskInfoPo.setId(id);
taskInfoPo.setAppId("test");
return taskInfoPo;
}
/**
* 根據taskInfo查詢subTaskInfo.
*
* @param taskInfoPo taskInfo
* @return subTaskInfo
*/
@Path("/getSubTaskInfo/") // url上沒有參數切诀,參數通過body傳入
@POST
@Consumes(MediaType.APPLICATION_JSON) // 聲明傳入參數是json格式
@Produces(MediaType.APPLICATION_JSON)
public SubTaskInfoPo getSubTaskInfo(TaskInfoPo taskInfoPo) {
SubTaskInfoPo subTaskInfoPo = new SubTaskInfoPo();
subTaskInfoPo.setId((int) System.currentTimeMillis());
subTaskInfoPo.setTaskId(taskInfoPo.getId());
subTaskInfoPo.setCreateTime(new Date());
return subTaskInfoPo;
}
/**
* 測試用的main函數.
*/
public static void main(String[] args) throws Exception {
Server server = new Server(8282); // 監(jiān)聽8282端口
ServletHolder servlet = new ServletHolder(ServletContainer.class);
// 設置初始化參數
servlet.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
servlet.setInitParameter("com.sun.jersey.config.property.packages", "com.tencent.awake.data.processing");
servlet.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true"); // 自動將對象映射成json返回
ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS);
handler.setContextPath("/");
handler.addServlet(servlet, "/*");
server.setHandler(handler);
server.start();
System.out.println("start...in 8282");
}
}
大部分要說明的東西都在注解里可以找到了倒庵,就不一一講解了,運行后會監(jiān)聽8282
端口(代碼里)噩咪,這段demo代碼提供了兩個接口胃碾,所以來看看怎么請求這兩個接口吧
我使用PostMan來模擬請求