前幾天去參加面試,面試官給了道機試題,由於沒接觸過,我就只能花很多時間去嘗試實現。題目大致如下:
準備
我們不強制要求您一定要用 java 語言開發,只要是可以在 JVM(Java7 或者 Java8) 上運行的語言都可以(Groovy, Scala… )。
我們不關心您使用什麼構建工具,但是您要做到 IDE 無關,並保證我們簽出即可運行。
我們不關心您使用什麼樣的持久化方式(可以使用內存),但是一定要內嵌到程序中,因爲我們不會專門再去安裝一個 Mysql 或者 MongoDB。
任務
Fork 這個 Repo(如果您不知道如何去做的話,Google 之)。
創建一個可編譯的工程。
我們的需求是一個交易記錄,交易信息包含「交易 ID」、「創建時間」、「交易狀態(例如是否交易成功)」、「交易類型(例如支付還是退款)」、「交易金額」、「交易幣種(例如美元還是人民幣)」、「客戶信息」
客戶信息包含「客戶 ID」、「客戶姓名」即可
通過 Rest 的方式暴露一個創建交易的接口
通過 Rest 的方式暴露一個按交易狀態查詢交易列表的接口
測試
使用用戶張三創建一條86元5角人民幣的交易記錄,驗證交易狀態爲等待付款,並且交易的金額是正確的。
使用你所習慣的測試框架,初始化3條交易成功信息,2條交易失敗信息。驗證查詢接口按全部狀態查詢共5條交易,只查詢成功的交易是3條,只查詢失敗的交易是2條。
看完這個題目,有三個問題:1.怎樣才能做到代碼與IDE無關,方便遷出?2.什麼樣的持久化方式可以嵌入到代碼當中?3.什麼是以REST方式去暴露一個接口?
第一個問題直到完成題目我也沒想出來合適的辦法;第二個問題我本打算將要操作的數據轉化爲對象,在進行序列化保存在文件中,使用的時候再逆序列化取出。但是考慮過於繁瑣,我直接就在程序當中聲明瞭那些對象並實例化使用;第三個問題,什麼是REST。經過一番調查,瞭解到一下信息:REST 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程序或設計就是 RESTful。REST 從資源的角度來觀察整個網絡,分佈在各處的資源由URI確定,而客戶端的應用通過URI來獲取資源的表示方式。獲得這些表徵致使這些應用程序轉變了其狀態。隨着不斷獲取資源的表示方式,客戶端應用不斷地在轉變着其狀態,所謂表述性狀態轉移(Representational State Transfer)。
下面就是我簡單的實現過程。
機緣巧合,在我尋找WebService框架時,看到了Jersey,覺得比較合適,就選擇了它。所以,先去Jersey官網下了個jar包:jersey-bundle-1.19.1.jar
然後打開我的IDE(老舊的Eclipse),建個Dynamic Web Project:ObjectToXML,導入jar包。建立com.rest.bean包,其中創建個Transaction.java文件
package com.rest.bean;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Transaction {
private String transactionID;// 交易ID
private Date creatTime;// 創建時間
private String transactionState;// 交易狀態
private String transactionTypes;// 交易類型
private String transactionAmount;// 交易金額
private String transactionCurrency;// 交易幣種
private String customerID;// 客戶ID
private String customerName;// 客戶姓名
public Transaction() {};
public Transaction(String transactionID, Date creatTime, String transactionState, String transactionTypes,
String transactionAmount, String transactionCurrency, String customerID, String customerName) {
super();
this.transactionID = transactionID;
this.creatTime = creatTime;
this.transactionState = transactionState;
this.transactionTypes = transactionTypes;
this.transactionAmount = transactionAmount;
this.transactionCurrency = transactionCurrency;
this.customerID = customerID;
this.customerName = customerName;
}
public String getTransactionID() {
return transactionID;
}
public void setTransactionID(String transactionID) {
this.transactionID = transactionID;
}
public Date getCreatTime() {
return creatTime;
}
public void setCreatTime(Date creatTime) {
this.creatTime = creatTime;
}
public String getTransactionState() {
return transactionState;
}
public void setTransactionState(String transactionState) {
this.transactionState = transactionState;
}
public String getTransactionTypes() {
return transactionTypes;
}
public void setTransactionTypes(String transactionTypes) {
this.transactionTypes = transactionTypes;
}
public String getTransactionAmount() {
return transactionAmount;
}
public void setTransactionAmount(String transactionAmount) {
this.transactionAmount = transactionAmount;
}
public String getTransactionCurrency() {
return transactionCurrency;
}
public void setTransactionCurrency(String transactionCurrency) {
this.transactionCurrency = transactionCurrency;
}
public String getCustomerID() {
return customerID;
}
public void setCustomerID(String customerID) {
this.customerID = customerID;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
}
新建個com.rest.resources包,其中創建個Resource.java文件
package com.rest.resources;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.rest.bean.Transaction;
import javax.ws.rs.GET;
@Path("/trans")
public class Resource {
/**
* 查詢交易信息
* @return
*/
@GET
@Path("/transactionState/{transactionState}")
@Produces(MediaType.APPLICATION_XML)
public List<Transaction> queryTrans(@PathParam("transactionState")String transactionState) {
List<Transaction> records = new ArrayList<Transaction>();
List<Transaction> trans = creatTran();
if("all".equals(transactionState)){
return trans;
}else if("success".equals(transactionState)){
for (Transaction transaction : trans) {
if("success".equals(transaction.getTransactionState())){
records.add(transaction);
}
}
return records;
}else if("failure".equals(transactionState)){
for (Transaction transaction : trans) {
if("failure".equals(transaction.getTransactionState())){
records.add(transaction);
}
}
return records;
}else{
return null;
}
}
private Date creatTime;
/**
* 添加交易信息
* @param transactionID
* @param transactionState
* @param transactionTypes
* @param transactionAmount
* @param transactionCurrency
* @param customerID
* @param customerName
* @return
*/
@GET
@Path("/transactionID/{transactionID}/transactionState/{transactionState}/transactionTypes/{transactionTypes}/transactionAmount/{transactionAmount}/transactionCurrency/{transactionCurrency}/customerID/{customerID}/customerName/{customerName}")
@Produces(MediaType.APPLICATION_XML)
public Transaction addTran(@PathParam("transactionID") String transactionID,
@PathParam("transactionState") String transactionState,
@PathParam("transactionTypes") String transactionTypes,
@PathParam("transactionAmount") String transactionAmount,
@PathParam("transactionCurrency") String transactionCurrency, @PathParam("customerID") String customerID,
@PathParam("customerName") String customerName) {
this.creatTime = new Date();
Transaction transaction = new Transaction(transactionID, creatTime, transactionState, transactionTypes, transactionAmount, transactionCurrency, customerID, customerName);
return transaction;
}
// 定義5個交易信息對象,3個成功,2個失敗
public static List<Transaction> creatTran() {
Transaction t1 = new Transaction("2016062801", new Date(), "success", "paid", "78.5", "RMB", "1001", "wang");
Transaction t2 = new Transaction("2016062802", new Date(), "success", "paid", "11.0", "RMB", "1001", "wang");
Transaction t3 = new Transaction("2016062803", new Date(), "success", "paid", "178.5", "RMB", "1001", "wang");
Transaction t4 = new Transaction("2016062804", new Date(), "failure", "paid", "8.5", "RMB", "1001", "wang");
Transaction t5 = new Transaction("2016062805", new Date(), "failure", "paid", "1.5", "RMB", "1001", "wang");
List<Transaction> tranLists = new ArrayList<Transaction>();
tranLists.add(t1);
tranLists.add(t2);
tranLists.add(t3);
tranLists.add(t4);
tranLists.add(t5);
return tranLists;
}
}
最後就是將該項目部署到tomcat中,然後在瀏覽器中去操作:
查詢全部交易記錄:
http://localhost:8080/ObjectToXML/rest/trans/transactionState/all
查詢交易成功的記錄:
http://localhost:8080/ObjectToXML/rest/trans/transactionState/success
查詢失敗的交易錄:
http://localhost:8080/ObjectToXML/rest/trans/transactionState/failure
添加交易記錄:
http://localhost:8080/ObjectToXML/rest/trans/transactionID/11101/transactionState/success/transactionTypes/付款/transactionAmount/78.5/transactionCurrency/rmb/customerID/1001/customerName/wang
這只是簡單的使用Jersey實現WebService的Demo。對於Jersey,感覺使用起來比較方便,而且這個框架可以很方便的將對象返回成XML文件,這樣就十分便捷了。
OS:我是在網上別人簡單的實例基礎上實現的這個題目,特喵地發給別人的代碼上居然忘記把人家原先註釋刪掉!居然還帶有時間!居然還是2014年!好吧!這很讓我丟人!可是還是我自己實現的啊!