Android Javaweb MySQL Tomcat 实现本地简易Api接口
需要配置两个jar包 jackson-all-2.8.0.jar json解析和mysql 连接 mysql-connector-java-5.1.7-bin.jar 文末 云盘地址压缩包包含。
使用Tomcat 本地服务,连接的是本地MYSQL 数据库world 数据库 city表,字段如图:
创建city的实体类:
public class CityBeen {
private String ID;
private String Name;
private String CountryCode;
private String District;
private String Population;
//get set
}
预期达到返回json格式,也就是包装成json格式:
单个的
{
"code": "ok",
"msg": "访问成功",
"time": 1510989490351,
"object": {
"id": "1",
"name": "Kabul",
"population": "1780000",
"countryCode": "AFG",
"district": "Kabol"
}
}
列表
{
"code": "ok",
"msg": "访问成功",
"time": 1511175554098,
"items": [
{ … },
{ … },
{ … },
]
}
这样子 可以找出其中的共同部分 就是code msg time ,可以据共同部分此做一个实体类的基类,包含code状态码 附加的msg以及时间戳 :
public class AbstractJsonObject {
private String code;
private String msg;
private Long time = new Date().getTime();
//省去get.set方法
}
然后单个、列表返回对象,可以继承AbstractJsonObject 类。
单个的SingleObject
public class SingleObject extends AbstractJsonObject{
private Object object;
// get set 方法
}
列表的 ListObject
public class ListObject extends AbstractJsonObject {
// 列表对象
private List<?> items;
public List<?> getItems() {
return items;
}
public void setItems(List<?> items) {
this.items = items;
}
}
实体类都有了,那么该考虑数据的问题,思想就是 通过连接mysql数据库进行数据表的增删改查。mysql 连接 mysql-connector-java-5.1.7-bin.jar包引进到项目里;新建数据库操作的Dbhelper工具类:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DbHelper {
public static final String url = "jdbc:mysql://localhost/world";
public static final String name = "com.mysql.jdbc.Driver";
public static final String user = "root";
public static final String password = "000000";
public Connection conn = null;
public PreparedStatement pst = null;
public DbHelper(String sql) {
try {
Class.forName(name);//
conn = DriverManager.getConnection(url, user, password);//
pst = conn.prepareStatement(sql);//
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
public void close() {
try {
this.conn.close();
this.pst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
其中要注意的是引用的包是java.sql.下的,所以把包都贴上来了,jdbc的url 要具体到对应的数据库,之外 Class.forName(name);e是一个静态方法,同样可以用来加载类,然后可以创建该类的对象,http://bbs.csdn.net/topics/390216436
诸多大佬有比较清楚的解释。
数据库连接通之后就是数据的获取和解析包装:
下文方法是新建dbhelper对象执行sql查询语句从city表获取所有数据:
public static List<CityBeen> getAllStudents() {
List<CityBeen> list = new ArrayList<CityBeen>();//list对象
String sql = null;
DbHelper db1 = null;
sql = "select * from city";// SQL
db1 = new DbHelper(sql);//创建DBHelper对象
ResultSet ret = null;//创建结果集对象,执行sql后返回的数据集合
try {
ret = db1.pst.executeQuery();//这个方法就类似于执行了SELECT语句一样!
while (ret.next()) {
String id = ret.getString(1);//第一列是id
String name = ret.getString(2);//第二列是name
String CountryCode = ret.getString(3);//第三列是CountryCode
String District = ret.getString(4);//第四列是District
String p= ret.getString(5);//第四列是Population
CityBeen city = new CityBeen();//创建city对象
city.setID(id);//设置id
city.setName(name);//设置name
city.setCountryCode(CountryCode);//设置CountryCode
city.setDistrict(District);//设置District
city.setPopulation(p);//设置District
list.add(city);//将city对象放置到列表中
} //循环从结果集中获取数据并设置到list列表对象中
ret.close();//关闭对象
db1.close();//关系数据库连接
} catch (SQLException e) {
e.printStackTrace();
} //
return list;//返回结果
}
但是 一个表的数据那么多显然不现实,那么还是要从分页查询,当然这样可以做测试来尝试是否连接成功。复习mysql 语法:
mysql中的sql语句: select * from 表名 limit 0,10;表示取表中的前10条数据(从第1条开始,取10条)
返回具体一个的sql很容易事项,那么需要两个值一个起始值和一个偏移量,也就是(页码-1)*一页数量,一页数量。
那么完整的 实现从数据库取值赋值的类为:
public class CityBusiness {
/**
* 获取所有数据
* @return
*/
public static List<CityBeen> getAllStudents() {
List<CityBeen> list = new ArrayList<CityBeen>();//list对象
String sql = null;
DbHelper db1 = null;
sql = "select * from city";// SQL
db1 = new DbHelper(sql);//创建DBHelper对象
ResultSet ret = null;//创建结果集对象,执行sql后返回的数据集合
try {
ret = db1.pst.executeQuery();//这个方法就类似于执行了SELECT语句一样!
while (ret.next()) {
String id = ret.getString(1);//第一列是id
String name = ret.getString(2);//第二列是name
String CountryCode = ret.getString(3);//第三列是CountryCode
String District = ret.getString(4);//第四列是District
String p= ret.getString(5);//第四列是Population
CityBeen city = new CityBeen();//创建city对象
city.setID(id);//设置id
city.setName(name);//设置name
city.setCountryCode(CountryCode);//设置CountryCode
city.setDistrict(District);//设置District
city.setPopulation(p);//设置District
list.add(city);//将city对象放置到列表中
} //循环从结果集中获取数据并设置到list列表对象中
ret.close();//关闭对象
db1.close();//关系数据库连接
} catch (SQLException e) {
e.printStackTrace();
} //
return list;//返回结果
}
/**
* 查询某一页
* @param page
* @param num
* @return
*/
public static List<CityBeen> getStudentsBypage(String pagenum,String datanum) {
List<CityBeen> list = new ArrayList<CityBeen>();//list对象
String sql = null;
DbHelper db1 = null;
int page=Integer.parseInt(pagenum);//第几页
int num=Integer.parseInt(datanum);//一页数量
int start=(page-1)*num ;
sql = "select * from city limit "+start+","+num;// SQL
db1 = new DbHelper(sql);//创建DBHelper对象
ResultSet ret = null;//创建结果集对象,执行sql后返回的数据集合
try {
ret = db1.pst.executeQuery();//这个方法就类似于执行了SELECT语句一样!
while (ret.next()) {
String id = ret.getString(1);//第一列是id
String name = ret.getString(2);//第二列是name
String CountryCode = ret.getString(3);//第三列是CountryCode
String District = ret.getString(4);//第四列是District
String p= ret.getString(5);//第四列是Population
CityBeen city = new CityBeen();//创建city对象
city.setID(id);//设置id
city.setName(name);//设置name
city.setCountryCode(CountryCode);//设置CountryCode
city.setDistrict(District);//设置District
city.setPopulation(p);//设置District
list.add(city);//将city对象放置到列表中
} //循环从结果集中获取数据并设置到list列表对象中
ret.close();//关闭对象
db1.close();//关系数据库连接
} catch (SQLException e) {
e.printStackTrace();
} //
return list;//返回结果
}
/**
* 通过id来获取某个城市数据
* @param _id
* @return
*/
public static CityBeen getStudentInfoById(String _id) {
String sql = null;
DbHelper db1 = null;
sql = "select * from city where id =" + _id;// sql
db1 = new DbHelper(sql);//创建DBHelper对象
ResultSet ret = null;//创建结果集对象
CityBeen city = new CityBeen();//创建对象
try {
ret = db1.pst.executeQuery();//正常来说,这个结果集只有一个对象
while (ret.next()) {
String id = ret.getString(1);//第一列是id
String name = ret.getString(2);//第二列是name
String CountryCode = ret.getString(3);//第三列是CountryCode
String District = ret.getString(4);//第四列是District
String Population= ret.getString(5);//第四列是Population
city.setID(id);//设置id
city.setName(name);//设置name
city.setCountryCode(CountryCode);//设置CountryCode
city.setDistrict(District);//设置District
city.setPopulation(Population);//设置District
} //循环从结果集中获取数据并设置到对象中(正常来说,这个循环只执行一次)
ret.close();//关闭对象
db1.close();//关系数据库连接
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //
return city;//返回结果
}
}
有三个静态类分别是返回所有记录和 分页查询和按照id 查询。
使用工厂模式思想,创建一个实现类实现接口,可以这样写:
首先是一个服务接口CityService:
public interface CityService {
public List<CityBeen> getAllCitys();
public CityBeen getCityByid(String id);
public List<CityBeen> getCitysByPage(String pagenum,String datanum);
}
实现类:
public class CityServiceImpl implements CityService{
@Override
public List<CityBeen> getAllCitys() {
// TODO Auto-generated method stub
return CityBusiness.getAllStudents();
}
@Override
public CityBeen getCityByid(String id) {
// TODO Auto-generated method stub
return CityBusiness.getStudentInfoById(id);
}
@Override
public List<CityBeen> getCitysByPage(String pagenum, String datanum) {
// TODO Auto-generated method stub
return CityBusiness.getStudentsBypage(pagenum, datanum);
}
}
这样子,要构建返回访问具体的对象时可以类似这样获取:
CityBeen city = new CityServiceImpl().getCityByid("1");//从数据库查找到id=1的城市
SingleObject object = new SingleObject();//构建单个返回对象
object.setObject(city);//返回内容
object.setcode("ok");//状态码
object.setmsg("获取信息成功")//附加信息
最后把object 解析成json返回http请求就可以了,每个返回对象都有code 的成员变量和msg成员变量,这个要定义为cons;
public class StatusCode {
public static String CODE_SUCCESS = "ok";//访问成功
public static String CODE_ERROR = "0001"; //访问错误
public static String CODE_ERROR_PARAMETER = "0002";//参数错误
public static String CODE_ERROR_PROGRAM = "0003";//程序异常
}
其实也可以把这两个成员变量拿出来做一个对象统一管理:
public class StatusObject {
// 状态码
private String code;
// 状态信息
private String msg;
public StatusObject(String code, String msg) {
super();
this.code = code;
this.msg = msg;
}
//get set
}
为了统一管理状态码和msg的关联,新建StatusHouse 类
public class StatusHouse {
public static StatusObject COMMON_STATUS_OK = new StatusObject(StatusCode.CODE_SUCCESS, "访问成功");
public static StatusObject COMMON_STATUS_ERROR = new StatusObject(StatusCode.CODE_ERROR,
"访问错误,错误码:(" + StatusCode.CODE_ERROR + ")");
public static StatusObject COMMON_STATUS_ERROR_PROGRAM = new StatusObject(StatusCode.CODE_ERROR_PROGRAM,
"程序异常,错误码:(" + StatusCode.CODE_ERROR_PROGRAM + ")");
public static StatusObject COMMON_STATUS_ERROR_PARAMETER = new StatusObject(StatusCode.CODE_ERROR_PARAMETER,
"参数错误,错误码:(" + StatusCode.CODE_ERROR_PARAMETER + ")");
}
在增加 AbstractJsonObject 增加set方法
public void setStatusObject(StatusObject statusObject) {
this.code = statusObject.getCode();
this.msg = statusObject.getMsg();
}
这样子就可以一下子设定code 和msg 。
到了这里 还需要把实体类转换成json 的工具类: jackson-all-2.8.0.jar包引进项目(因为参考别人的,所以就直接拿过来用了)
json工具类:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JackJsonUtils {
static ObjectMapper objectMapper;
/**
* 解析json
*
* @param content
* @param valueType
* @return
*/
public static <T> T fromJson(String content, Class<T> valueType) {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
}
try {
return objectMapper.readValue(content, valueType);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成json
*
* @param object
* @return
*/
public static String toJson(Object object) {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
}
try {
return objectMapper.writeValueAsString(object);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
这样子解析也完了,就差到web访问了,web涉及到可能乱码的问题所以也需要一个工具。
public class ResponseUtils {
/**
* 返回json 串
*
* @param response
* @param text
*/
public static void renderJson(HttpServletResponse response, String text) {
// System.out.print(text);
render(response, "text/plain;charset=UTF-8", text);
}
/**
* 发送内容。使用UTF-8编码。
*
* @param response
* @param contentType
* @param text
*/
public static void render(HttpServletResponse response, String contentType, String text) {
response.setContentType(contentType);
response.setCharacterEncoding("utf-8");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
try {
response.getWriter().write(text);
} catch (IOException e) {
}
}
}
最后就差sel
/**
* Servlet implementation class CityServleet
*/
@WebServlet("/CityServleet")
public class CityServleet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public CityServleet() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
switch (action) {
case "all":
List<CityBeen> list = new CityServiceImpl().getAllCitys();
ListObject listObject = new ListObject();
listObject.setItems(list);
listObject.setStatusObject(StatusHouse.COMMON_STATUS_OK);
String responseText = JackJsonUtils.toJson(listObject);
ResponseUtils.renderJson(response, responseText);
break;
case "id":
CityBeen city = new CityServiceImpl().getCityByid("1");
SingleObject object = new SingleObject();
object.setStatusObject(StatusHouse.COMMON_STATUS_OK);
object.setObject(city);
ResponseUtils.renderJson(response, JackJsonUtils.toJson(object));
break;
case "page":
String page = request.getParameter("page");
String num = request.getParameter("num");
List<CityBeen> list2 = new CityServiceImpl().getCitysByPage(page, num);
ListObject listObject2 = new ListObject();
listObject2.setItems(list2);
listObject2.setStatusObject(StatusHouse.COMMON_STATUS_OK);
String responseText2 = JackJsonUtils.toJson(listObject2);
ResponseUtils.renderJson(response, responseText2);
break;
default:
SingleObject object2 = new SingleObject();
object2.setStatusObject(StatusHouse.COMMON_STATUS_ERROR_PARAMETER);
object2.setObject("");
ResponseUtils.renderJson(response, JackJsonUtils.toJson(object2));
break;
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
可以看到不管四post请求还是get 请求都是要先获取action 参数来具体下一步动作。最后返回数据。
最后使用tomcat run on sever...测试。
注意:jackson-all-2.8.0.jar json解析和mysql 连接 mysql-connector-java-5.1.7-bin.jar要复制一份到tomcat的安装路径的lib下,否则会报 notfound错误。
测试一下:
项目链接:
https://github.com/silencefun/WebTest
压缩包地址(包含jar包):https://pan.baidu.com/s/1gfdBrpx 密码: vg6r
参考:http://blog.csdn.net/zxw136511485/article/details/51437115