RESTful API实现APP订餐实例

web网站如下:




客户端APP查询以及订餐:



服务器端接收客户订单信息:




客户端通过HTTP+JSON来调用这些服务。


首先是客户端:

客户端要用这些jar文件,不要忘记放进去:



首先是HttpHelper.java

package my;

import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class HttpHelper {
	//HTTP GET测试
	public static String doGet(String url) throws Exception{
		
		CloseableHttpClient httpclient=HttpClients.createDefault();
		HttpGet httpget=new HttpGet(url);
		CloseableHttpResponse response=httpclient.execute(httpget);
		
		try {
			StatusLine statusLine=response.getStatusLine();
			int status=statusLine.getStatusCode();
			if(status!=200) {
				throw new Exception("Http GET出错:"+status+", "+statusLine.getReasonPhrase());
			}
			HttpEntity entity=response.getEntity();
			if(entity!=null) {
				long len=entity.getContentLength();
				if(len!=-1&&len<16384) {
					String replyText=EntityUtils.toString(entity);
					return replyText;
				}
				else {
					//Stream content out
				}
			}
		}
		finally {
			response.close();
		}
		
		return null;
	}
	
	//HTTP POST测试
	public static String doPost(String url,String reqText) throws Exception{
		CloseableHttpClient httpclient=HttpClients.createDefault();
		HttpPost httppost=new HttpPost(url);
		
		//上行数据
		StringEntity dataSent=new StringEntity(reqText,ContentType.create("text/plain","UTF-8"));
		httppost.setEntity(dataSent);
		
		CloseableHttpResponse response=httpclient.execute(httppost);
		try {
			StatusLine statusLine=response.getStatusLine();
			int status=statusLine.getStatusCode();
			if(status!=200) {
				throw new Exception("HTTP POST出错:"+status+", "+statusLine.getReasonPhrase());
			}
			
			//下行数据
			HttpEntity dataRecv=response.getEntity();
			if(dataRecv!=null) {
				long len=dataRecv.getContentLength();
				if(len!=-1&&len<16384) {
					String replyText=EntityUtils.toString(dataRecv);
					return replyText;
				}
				else {
					//Stream content out
				}
			}
		}
		finally {
			response.close();
		}
		
		return null;
	}
	
}

然后是Booking.java

package my;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.json.JSONArray;
import org.json.JSONObject;

public class Booking {
	
	String baseUrl="http://127.0.0.1:8080/myweb";
	
	private void book(int foodId) throws Exception{
		JSONObject jsReq=new JSONObject();
		jsReq.put("foodId", foodId);
		jsReq.put("time", "2017-02-11 00:00:00");
		
		JSONObject jsClient=new JSONObject();
		jsClient.put("clientName", "朱小明");
		jsClient.put("clientPhone", "13156254789");
		jsClient.put("clientAddress", "XXX路XX号XX楼");
		jsReq.put("client", jsClient);
		
		String replyText=HttpHelper.doPost(baseUrl+"/api/Book", jsReq.toString());
		
		//应答消息,错误检测
		JSONObject jsReply=new JSONObject(replyText);
		int error=jsReply.getInt("error"); 
		String reason=jsReply.getString("reason");
		if(error!=0) {
			System.out.println("服务器返回错误!error="+error+", reason:"+reason);
			return;
		}
		JSONObject data=jsReply.getJSONObject("data");
		System.out.println("订单已下达!订单号码:"+data.getInt("bookId"));
	}
	
	//RESTful形式的API
	private void list() throws Exception{
		String replyText=HttpHelper.doGet(baseUrl+"/api/ListFood");
		
		//错误码检测
		JSONObject jsReply=new JSONObject(replyText);
		int error=jsReply.getInt("error");
		String reason=jsReply.getString("reason");
		if(error!=0) {
			System.out.println("服务器返回错误!error"+error+" ,reason:"+reason);
			return;
		}
		
		//把电影列表显示给用户
		JSONArray data=jsReply.getJSONArray("data");
		for(int i=0;i<data.length();i++) {
			JSONObject m=data.getJSONObject(i);
			String line=String.format("商品号:[%d]     商品名【%s】    价格: %s元     饮料:%s    商家:%s  ", 
					m.getInt("id"),
					m.getString("title"),
					m.getString("price"),
					m.getString("drink"),
					m.getString("merchant")
					);
			System.out.println(line);
		}
	}
	
	public void handleCommand(String[] argv) throws Exception{
		if(argv[0].equals("list")) {
			list();
		}
		else if(argv[0].equals("book")&&argv.length==2) {
			book(Integer.valueOf(argv[1]));
		}
		else {
			System.out.println("无效命令或无效参数!");
		}
	}
	
	//用户主界面
	public void shell() throws Exception{
		InputStreamReader m=new InputStreamReader(System.in);
		BufferedReader reader=new BufferedReader(m);
		
		while(true) {
			System.out.print("\n>");				//输入提示
			String nextline=reader.readLine();
			if(nextline==null)	break;
			
			String[] argv=nextline.split(" ");
			if(argv.length==0)	continue;
			if(argv[0].equals("quit"))	break;
			
			try {
				handleCommand(argv);
			}
			catch(Exception e) {
				e.printStackTrace();
			}
		}
		reader.close();
	}
	

	public static void main(String[] args) {
		try {
			Booking t=new Booking();
			t.shell();
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}

}


服务器端:要使用json的jar




book.jsp代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'book.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    This is my JSP page. <br>
  </body>
</html>


list_food.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>菜单列表</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
	
	<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
	<script src="jquery/jquery.js"></script>
	<script src="bootstrap/js/bootstrap.min.js"></script>
	<script src="jquery/jquery.json-2.3js"></script>
	
	<script>
	
	function trace(msg){
		try{
			console.log(msg);
		}
		catch(err){
		}
		
		//页面加载后的初始化工作
		$(document).ready(function(){
		});
	}
	
	</script>

  </head>
  
  <body>
  	
  	<div class="container">
  	外卖列表
  	</div>
  	
  	<table class="table">
  		<tr><th>菜名</th><th>价格</th><th>饮料</th><th>商家</th></tr>
  		<tr>
    	<td> <a href="book.jsp?foodId=100001"> 脆皮鸡 </a></td>
    		<td> 15 </td>
    		<td> 冰红茶 </td>
    		<td> 美团 </td>
    	</tr>
    	<tr>
    	<td> <a href="book.jsp?foodId=10002"> 黄焖鸡 </a></td>
    		<td> 18 </td>
    		<td> 雪碧 </td>
    		<td> 饿了吗 </td>
    	</tr>
    	<tr>
    		<td> <a href="book.jsp?foodId=10003"> 重庆鸡公煲 </a></td>
    		<td> 18 </td>
    		<td> 矿泉水 </td>
    		<td> 百度外卖 </td>
    	</tr>
  	</table>
  	
  </body>
</html>


这个web.xml要做如下配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>Book</servlet-name>
    <servlet-class>my.BookServlet</servlet-class>
  </servlet>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>ListFood</servlet-name>
    <servlet-class>my.ListFoodServlet</servlet-class>
  </servlet>


  <servlet-mapping>
    <servlet-name>Book</servlet-name>
    <url-pattern>/api/Book</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ListFood</servlet-name>
    <url-pattern>/api/ListFood</url-pattern>
  </servlet-mapping>	
  <welcome-file-list>
    <welcome-file>list_food.jsp</welcome-file>
  </welcome-file-list>
</web-app>


关于java的class,从tcp stream读取数据的文件

Util.java

package my;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class Util {
	// 从TCP Stream中读取时,要反复读取,直接读完
		public static String readAsText(InputStream streamIn, String charset) 
				throws IOException {
			ByteArrayOutputStream cache = new ByteArrayOutputStream(4096);  
	        byte[] data = new byte[1024];  
	        while (true){
	        	int len = streamIn.read(data);
	        	if(len < 0) // 连接已经断开
	        		break;
	        	if(len == 0) // 数据未完
	        		continue;
	        	// 缓存起来
	        	cache.write(data, 0, len);
	        	
	        	if(cache.size() > 1024*16) // 上限, 最多读取16KB
	        		break;
	        }       
	        return cache.toString(charset);
		}
}


下面是两个Servlet

一个是BookServlet.java

package my;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONObject;

public class BookServlet extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException{
		// 读取用户请求
		String reqText = Util.readAsText(request.getInputStream(), "UTF-8");	 
	    JSONObject jsReq = new JSONObject(reqText);
	    
	    JSONObject client = jsReq.getJSONObject("client"); // 客户的快递地址
	    String clientName = client.getString("clientName"); 
	    String clientPhone = client.getString("clientPhone"); 
	    String clientAddress = client.getString("clientAddress");
	    
	    int foodId = jsReq.getInt("foodId");
	    String time = jsReq.getString("time");
	    Date day=new Date();    

	    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
	    
		// 构造JSON
		JSONObject jsReply = new JSONObject();
		jsReply.put("error", 0);
		jsReply.put("reason", "OK");
		
		// 生成订单号 (模拟)
		int bookId = (int) (Math.random() * 1000);
		JSONObject data = new JSONObject();
		data.put("bookId", bookId);
		jsReply.put("data", data);
		
	    System.out.println("客户订单:");
	    System.out.println("订单号:"+bookId);
	    System.out.println("商品号:"+foodId);
	    System.out.println("客户名:"+clientName);
	    System.out.println("客户电话:"+clientPhone);
	    System.out.println("客户地址:"+clientAddress);
	    System.out.println("下单时间:"+df.format(day));
	    
	    
		
		String replyText = jsReply.toString();

		// 采用Content-Length方式
		byte[] outdata = replyText.getBytes("UTF-8");
		response.setContentType("text/plain");  
		response.setCharacterEncoding("UTF-8");	
		response.setContentLength(outdata.length);
		
		OutputStream out = response.getOutputStream();
		out.write(outdata);
		out.close();
	}


一个·是:ListFoodServlet.java

package my;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONArray;
import org.json.JSONObject;

public class ListFoodServlet extends HttpServlet {

	/**
	 * Constructor of the object.
	 */
	public ListFoodServlet() {
		super();
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}

	/**
	 * The doGet method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		//返回电影列表给用户 
		JSONArray movies = new JSONArray();
		
		JSONObject m1 = new JSONObject();
		m1.put("id", 100001);
		m1.put("title", "脆皮鸡");
		m1.put("drink", "冰红茶");
		m1.put("price", "15");
		m1.put("merchant", "美团");
		movies.put(m1);
		
		JSONObject m2 = new JSONObject();
		m2.put("id", 100002);
		m2.put("title", "黄焖鸡");
		m2.put("drink", "雪碧");
		m2.put("price", "18");
		m2.put("merchant", "饿了吗");
		movies.put(m2);
		
		JSONObject m3 = new JSONObject();
		m3.put("id", 100003);
		m3.put("title", "重庆鸡公煲");
		m3.put("drink", "矿泉水");
		m3.put("price", "18");
		m3.put("merchant", "百度外卖");
		movies.put(m3);
		
		JSONObject jsReply = new JSONObject();
		jsReply.put("error", 0);  // 错误码,0表示成功
		jsReply.put("reason", "OK"); // 错误描述
		jsReply.put("data", movies); // 数据
		
		String replyText = jsReply.toString();

		// 应答: 为了方便用客户端的解析, 采用Content-Length方式
		byte[] outdata = replyText.getBytes("UTF-8");
		response.setContentType("text/plain");  // Content-Type
		response.setCharacterEncoding("UTF-8");	// charset	
		response.setContentLength(outdata.length);// Content-Length
		
		OutputStream out = response.getOutputStream();
		out.write(outdata);
		out.close();
	}
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值