前几天去参加面试,面试官给了道机试题,由于没接触过,我就只能花很多时间去尝试实现。题目大致如下:
准备
我们不强制要求您一定要用 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年!好吧!这很让我丢人!可是还是我自己实现的啊!