Java开发项目中,有时会访问远程http服务器上的数据,数据可能是xml格式或者json格式等。这里我们通过例子来看一下两种实现方式的对比。
本例子中有一个servlet,对外提供json格式的雇员信息查询。Servlet访问数据库的员工表,保存了员工的信息,如下:
EID NAME SURNAME GENDER STATE BIRTHDAY HIREDATE DEPT SALARY
1 Rebecca Moore F California 1974-11-20 2005-03-11 R&D 7000
2 Ashley Wilson F New York 1980-07-19 2008-03-16 Finance 11000
3 Rachel Johnson F New Mexico 1970-12-17 2010-12-01 Sales 9000
4 Emily Smith F Texas 1985-03-07 2006-08-15 HR 7000
5 Ashley Smith F Texas 1975-05-13 2004-07-30 R&D 16000
6 Matthew Johnson M California 1984-07-07 2005-07-07 Sales 11000
7 Alexis Smith F Illinois 1972-08-16 2002-08-16 Sales 9000
8 Megan Wilson F California 1979-04-19 1984-04-19 Marketing 11000
9 Victoria Davis F Texas 1983-12-07 2009-12-07 HR 3000
…
Servlet的doGet函数,接收json格式的雇员id字符串,通过数据库查询对应的雇员信息,形成json格式的雇员信息清单返回。下面的代码省略了读取数据库,生成雇员清单的过程:
protected void doGet(HttpServletRequestreq, HttpServletResponse resp) throws ServletException, IOException {
StringinputString=(String) req.getParameter("input");
//inputString输入值是:"[{EID:8},{EID:32},{EID:44}]";
if(inputString==null) inputString="";
StringoutputString ="";
{...}//此处省略通过inputString查询数据库生成outputString的代码
//outputString生成结果是
//"[{EID:8,NAME:"Megan",SURNAME:"Wilson",GENDER:"F",STATE:\...";
resp.getOutputStream().println(outputString);
resp.setContentType("text/json;charset=GBK");
}
Java程序要访问这个httpservlet,取得EID为1、2的员工信息,之后按照EID的降序排列。具体思路是:
1、 引入开源项目httpclient,访问servlet取得结果。
2、 引入开源项目json-lib,解析返回的字符串。
3、 使用比较法,按照EID的降序排列。
示例代码如下:
public static voidmyHTTP() throws Exception{
//下面定义http的url
URLurl =
newURL("http://localhost:6080/myweb/servlet/testServlet?input=[{EID:1},{EID:2}]");
URIuri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),url.getPort(), url.getPath(), url.getQuery(), null);
//下面发出http的请求,并接受返回结果
CloseableHttpClientclient = HttpClients.createDefault();
HttpGetget = new HttpGet(uri);
CloseableHttpResponseresponse = client.execute(get);
StringmyJson=EntityUtils.toString(response.getEntity());
//下面将读取的内容解析成json对象
JSONArray jsonArr = JSONArray.fromObject(myJson );
//下面完成json数据排序(降序)
JSONObject jObject = null;
for(inti = 0;i<jsonArr.size();i++){
longl = Long.parseLong(jsonArr.getJSONObject(i).get("EID").toString());
for(intj = i+1; j<jsonArr.size();j++){
longnl = Long.parseLong(jsonArr.getJSONObject(j).get("EID").toString());
if(l<nl){
jObject= jsonArr.getJSONObject(j);
jsonArr.set(j,jsonArr.getJSONObject(i));
jsonArr.set(i,jObject);
}
}
}
System.out.println(jsonArr.toString());
}
需要引入开源项目json-lib,其依赖的包是:
json-lib-2.4-jdk15.jar
ezmorph-1.0.6.jar
commons-lang.jar
commons-beanutils.jar
commons-logging.jar
commons-collections.jar
引入开源项目httpclient,其依赖的包是:
commons-codec-1.6.jar
commons-logging-1.1.3.jar
fluent-hc-4.3.5.jar
httpclient-4.3.5.jar
httpclient-cache-4.3.5.jar
httpcore-4.3.2.jar
httpmime-4.3.5.jar
从这个例子来看,Java要完成需求,需要引入两个开源项目,jar包也可能有重复的地方。同时,虽然myHTTP函数已经实现了http数据访问和排序,但是通用性并不强。如果需要按照升序排序或者按照多个字段排序的话,就需要改程序了。如果希望myHTTP能够支持通用的,类似SQL那样灵活的数据访问和处理,就要实现动态表达式解析,代码会很复杂。
Java实现http数据的访问和处理,也可以用集算器esProc来配合Java实现,好处是只需要引入一个项目,就能够用简单的代码实现动态的访问和排序。集算器可以很方便完成远程http服务器的数据的读取、计算。为了实现动态的处理,可以把排序表达式作为一个参数传递给esProc,如下图:
sortBy参数的值为:EID:-1。集算器访问http数据的程序只需要6行代码,如下:
A1:定义了要传给servlet的输入参数,也就是json格式的员工id列表。
A2:定义了httpfile对象,url是
http://localhost:6080/myweb/servlet/testServlet?input=[{EID:1},{EID:2}],字符集是GBK。
A3:读取A2这个httpfile对象返回的结果。
A4:逐个解析每个员工的json格式的信息,整理成一个序列。
A5:对数据排序,集算器先计算宏${sortBy}中的参数sortBy,之后执行的语句是A4.sort(EID:-1),也就是按照EID的降序排序;
A6:将A5中的结果返回给调用这段集算器程序的Java代码。
如果排序的字段和方式发生变化,不用修改程序,只要改变sortBy参数即可。例如:要按照eid的升序和name的降序排序,要将sortBy改为:EID:1,NAME:-1即可,最终执行的排序语句是A4.sort(EID:1,NAME:-1)。
在Java程序中可以很方便的调用这段esProc程序,使用esProc提供的jdbc即可完成。将上述esProc程序保存为test.dfx文件的话,Java调用的代码如下:
//建立esProc jdbc连接
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
//调用esProc 程序(存储过程),其中test是dfx的文件名
com.esproc.jdbc.InternalCStatementst;
st =(com.esproc.jdbc.InternalCStatement)con.prepareCall("calltest(?)");
//设置参数
st.setObject(1,"EID:1,NAME:-1");//集算器的输入参数,也就是动态排序表达式
//执行esProc存储过程
ResultSetset=st.executeQuery();
while(set.next())System.out.println("EID="+set.getInt("EID"));
这里的集算器代码比较简单,可以在Java程序中直接调用,不必再写集算器的脚本文件(比如上边的test.dfx)。具体代码如下:
st=(com.esproc.jdbc.InternalCStatement)con.createStatement();
ResultSet set=st.executeQuery("=httpfile(\"http://localhost:6080/myweb/servlet/testServlet?input=[{EID:1},{EID:2}]\",\"GBK\").read()[email protected]().sort(EID:1,NAME:-1)");
上面的Java代码直接调用了一句集算器语句:从http服务器读取数据,按照指定字段排序之后,将结果以ResultSet返回给Java程序。