Javaweb MySQL 实现本地Android数据Api接口

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表,字段如图:


image.png

创建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错误。

测试一下:


image.png

项目链接:
https://github.com/silencefun/WebTest

压缩包地址(包含jar包):https://pan.baidu.com/s/1gfdBrpx 密码: vg6r

参考:http://blog.csdn.net/zxw136511485/article/details/51437115

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,837评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,925评论 6 342
  • 烤肉质感画的我想死,还是要多看看大神是怎么画的⁽˙³˙⁾(๑•́ ₃ •̀๑)⁽˙³˙⁾
    水墨镇阅读 523评论 1 3
  • 2017-9-11学经汇报: 一、学经日期:2017年9月11日 农历七月廿一 多云 星期一 宝贝年龄...
    b0a4ca4b06a4阅读 209评论 0 0
  • 三月莺飞花渐醒 迢迢年华难相依 无事春风惹床帘 应是嘲我浓情意 夜半江竹人独影 淡酒难穷此深情 不恨今生相识短 只...
    墨zlr阅读 275评论 0 4