转载自http://www.cnblogs.com/yzxk/p/4749440.html


一、开发环境的部署

程序结构:

Android+servlet+service+MySQL

仅供参考:能实现相关功能即可

操作系统:ubuntu 14.10

数据库:mysql-5.5    数据库工具:emma

服务器:tomcat      服务器工具:Myeclipse 10

安卓端:真机 android4.4  安卓端工具:eclipse+adt

注意:

程序调试过程可能会产生乱码,只需保持所有工具编码方式相同即可。

 

二、数据库设计

表名:student

视图:

 

 

三、服务器端设计

1、新建Web Project,命名为HelloWeb

2、项目结构图如下:

 LogLet类和RegLet类分别用于处理客户端的登陆和注册请求;Service类用于完成servlet对数据库的具体操作;DBManager类用于进行数据库基本操作;

 左侧是项目图,右侧是web.xml配置文件截图。

   

 

3、项目代码:

 DBManager.Java

 <1> 单例模式构建DBManager对象;       

 <2> 定义数据库连接、关闭以及增删改查的基本操作,返回结果集。

package com.db;import java.sql.*;public class DBManager {    // 数据库连接常量    public static final String DRIVER = "com.mysql.jdbc.Driver";    public static final String USER = "root";    public static final String PASS = "root";    public static final String URL = "jdbc:mysql://localhost:3306/test";    // 静态成员,支持单态模式    private static DBManager per = null;    private Connection conn = null;    private Statement stmt = null;    // 单态模式-懒汉模式    private DBManager() {    }    public static DBManager createInstance() {        if (per == null) {            per = new DBManager();            per.initDB();        }        return per;    }    // 加载驱动    public void initDB() {        try {            Class.forName("com.mysql.jdbc.Driver");        } catch (Exception e) {            e.printStackTrace();        }    }    // 连接数据库,获取句柄+对象    public void connectDB() {        System.out.println("Connecting to database...");        try {            conn = DriverManager.getConnection(URL, USER, PASS);            stmt = conn.createStatement();        } catch (SQLException e) {            e.printStackTrace();        }        System.out.println("SqlManager:Connect to database successful.");    }    // 关闭数据库 关闭对象,释放句柄    public void closeDB() {        System.out.println("Close connection to database..");        try {            stmt.close();            conn.close();        } catch (SQLException e) {            e.printStackTrace();        }        System.out.println("Close connection successful");    }    // 查询    public ResultSet executeQuery(String sql) {        ResultSet rs = null;        try {            rs = stmt.executeQuery(sql);        } catch (SQLException e) {            e.printStackTrace();        }        return rs;    }    // 增添/删除/修改    public int executeUpdate(String sql) {        int ret = 0;        try {            ret = stmt.executeUpdate(sql);        } catch (SQLException e) {            e.printStackTrace();        }        return ret;    }}

 

Service.java

  写到这里,可以预见:下一个类会通过调用本类方法完成登陆/注册的服务。

package com.service;import java.sql.ResultSet;import java.sql.SQLException;import com.db.DBManager;public class Service {    public Boolean login(String username, String password) {        // 获取Sql查询语句        String logSql = "select * from user where username ='" + username                + "' and password ='" + password + "'";        // 获取DB对象        DBManager sql = DBManager.createInstance();        sql.connectDB();        // 操作DB对象        try {            ResultSet rs = sql.executeQuery(logSql);            if (rs.next()) {                sql.closeDB();                return true;            }        } catch (SQLException e) {            e.printStackTrace();        }        sql.closeDB();        return false;    }    public Boolean register(String username, String password) {        // 获取Sql查询语句        String regSql = "insert into student values('"+ username+ "','"+ password+ "') ";        // 获取DB对象        DBManager sql = DBManager.createInstance();        sql.connectDB();        int ret = sql.executeUpdate(regSql);        if (ret != 0) {            sql.closeDB();            return true;        }        sql.closeDB();        return false;    }}

 

LogLet.java

  一个简单的Servlet,用于处理Http请求(get/post)。RegLet.java和该类近乎相同,此处省去~

package com.servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.service.Service;public class LogLet extends HttpServlet {    private static final long serialVersionUID = 369840050351775312L;    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 接收客户端信息        String username = request.getParameter("username");        username = new String(username.getBytes("ISO-8859-1"), "UTF-8");        String password = request.getParameter("password");        System.out.println(username + "--" + password);        // 新建服务对象        Service serv = new Service();        // 验证处理        boolean loged = serv.login(username, password);        if (loged) {            System.out.print("Succss");            request.getSession().setAttribute("username", username);            // response.sendRedirect("welcome.jsp");        } else {            System.out.print("Failed");        }        // 返回信息到客户端        response.setCharacterEncoding("UTF-8");        response.setContentType("text/html");        PrintWriter out = response.getWriter();        out.print("用户名:" + username);        out.print("密码:" + password);        out.flush();        out.close();    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {    }}

 

 

四、客户端设计

1、新建Android App Project,命名为AndroidHTTPDemo

2、现在开始思考需要什么东西… 

 <1> 登陆和注册页面:布局文件

   login.xml , register.xml

 <2> 登陆和注册页面对应的Activity组件,在activity中进行具体操作

   login.java , register.java

 <3> 能够实现Http以get/post方式通信的类

   WebService.java , WebServicePost.java

 <4> 网络通信权限

        
           

    OK,项目结构出炉,右侧是Manifeast配置文件的主要内容

3、现在,我们开始关注具体的代码。

  <1> 首先要做的,登陆注册界面,这个不用多说。我直接放图,大致就是下面这个样子,大家可以按照自己爱好设计。

  

<2> 在服务器端编程时我们了解到:服务器端接收客户端发送的信息,对信息进行一系列处理后,最终信息返回到客户端。

  首先要想的,就是获取信息并发送出去,然后接收信息并显示出来。

 (网络服务由于耗时问题,放在主线程很可能由于网络故障导致ANR;所以要开辟子线程留给http网络服务。当然不使用主线程也可以,只是不推荐)

      

<3> Login.java 有三点需要注意

  第一个是检测网络状态,只能检测流量,无法检测wifi;

  第二个是在子线程中,不能更改主线程的页面值,这里用了handle解决。

  第三个是这里有get/post两种http请求方式,两个实现类,。

package com.httpdemo;import com.rxz.androidhttpdemo.R;import com.web.WebService;import com.web.WebServicePost;import android.app.Activity;import android.app.ProgressDialog;import android.content.Context;import android.content.Intent;import android.net.ConnectivityManager;import android.os.Bundle;import android.os.Handler;import android.view.Gravity;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class Login extends Activity implements OnClickListener {    // 登陆按钮    private Button logbtn;    // 调试文本,注册文本    private TextView infotv, regtv;    // 显示用户名和密码    EditText username, password;    // 创建等待框    private ProgressDialog dialog;    // 返回的数据    private String info;    // 返回主线程更新数据    private static Handler handler = new Handler();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.login);        // 获取控件        username = (EditText) findViewById(R.id.user);        password = (EditText) findViewById(R.id.pass);        logbtn = (Button) findViewById(R.id.login);        regtv = (TextView) findViewById(R.id.register);        infotv = (TextView) findViewById(R.id.info);        // 设置按钮监听器        logbtn.setOnClickListener(this);        regtv.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {        case R.id.login:            // 检测网络,无法检测wifi            if (!checkNetwork()) {                Toast toast = Toast.makeText(Login.this,"网络未连接", Toast.LENGTH_SHORT);                toast.setGravity(Gravity.CENTER, 0, 0);                toast.show();                break;            }            // 提示框            dialog = new ProgressDialog(this);            dialog.setTitle("提示");            dialog.setMessage("正在登陆,请稍后...");            dialog.setCancelable(false);            dialog.show();            // 创建子线程,分别进行Get和Post传输            new Thread(new MyThread()).start();            break;        case R.id.register:            Intent regItn = new Intent(Login.this, Register.class);            // overridePendingTransition(anim_enter);            startActivity(regItn);            break;        }        ;    }    // 子线程接收数据,主线程修改数据    public class MyThread implements Runnable {        @Override        public void run() {            info = WebService.executeHttpGet(username.getText().toString(), password.getText().toString());            // info = WebServicePost.executeHttpPost(username.getText().toString(), password.getText().toString());            handler.post(new Runnable() {                @Override                public void run() {                    infotv.setText(info);                    dialog.dismiss();                }            });        }    }    // 检测网络    private boolean checkNetwork() {        ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);        if (connManager.getActiveNetworkInfo() != null) {            return connManager.getActiveNetworkInfo().isAvailable();        }        return false;    }}

 

<4> WebService.java   

  这里的IP是你的服务器IP,不确定时看下是否能用手机ping工具ping通。

  ① 你的服务器端程序已发布到互联网:这好办,就是你的IP地址。

  ② 你是在本地电脑上,这要求你的真机和你的电脑在同一个局域网。两种较方便的方法:路由器/笔记本的无线网卡

   conn.setConnectTimeout(3000);需要设置超时时间,否则会执行默认超时时间,30s ?

package com.web;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;public class WebService {    private static String IP = "10.42.0.1:8080";    // 通过Get方式获取HTTP服务器数据    public static String executeHttpGet(String username, String password) {        HttpURLConnection conn = null;        InputStream is = null;        try {            // 用户名 密码            // URL 地址            String path = "http://" + IP + "/HelloWeb/LogLet";            path = path + "?username=" + username + "&password=" + password;            conn = (HttpURLConnection) new URL(path).openConnection();            conn.setConnectTimeout(3000); // 设置超时时间            conn.setReadTimeout(3000);            conn.setDoInput(true);            conn.setRequestMethod("GET"); // 设置获取信息方式            conn.setRequestProperty("Charset", "UTF-8"); // 设置接收数据编码格式            if (conn.getResponseCode() == 200) {                is = conn.getInputStream();                return parseInfo(is);            }        }catch (Exception e) {            e.printStackTrace();        } finally {            // 意外退出时进行连接关闭保护            if (conn != null) {                conn.disconnect();            }            if (is != null) {                try {                    is.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return null;    }    // 将输入流转化为 String 型     private static String parseInfo(InputStream inStream) throws Exception {        byte[] data = read(inStream);        // 转化为字符串        return new String(data, "UTF-8");    }    // 将输入流转化为byte型     public static byte[] read(InputStream inStream) throws Exception {        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();        byte[] buffer = new byte[1024];        int len = 0;        while ((len = inStream.read(buffer)) != -1) {            outputStream.write(buffer, 0, len);        }        inStream.close();        return outputStream.toByteArray();    }}

 

<5> WebServicePost.java

package com.web;import java.io.InputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.message.BasicNameValuePair;import org.apache.http.params.CoreConnectionPNames;public class WebServicePost {    private static String IP = "10.42.0.1:8080";    // 通过 POST 方式获取HTTP服务器数据    public static String executeHttpPost(String username, String password) {        try {            String path = "http://" + IP + "/HelloWeb/LogLet";            // 发送指令和信息            Map params = new HashMap();            params.put("username", username);            params.put("password", password);            return sendPOSTRequest(path, params, "UTF-8");        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    // 处理发送数据请求    private static String sendPOSTRequest(String path, Map params, String encoding) throws Exception {        List pairs = new ArrayList();        if (params != null && !params.isEmpty()) {            for (Map.Entry entry : params.entrySet()) {                pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));            }        }        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs, encoding);        HttpPost post = new HttpPost(path);        post.setEntity(entity);        DefaultHttpClient client = new DefaultHttpClient();        // 请求超时        client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);        // 读取超时        client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);        HttpResponse response = client.execute(post);        // 判断是否成功收取信息        if (response.getStatusLine().getStatusCode() == 200) {            return getInfo(response);        }        // 未成功收取信息,返回空指针        return null;    }    // 收取数据    private static String getInfo(HttpResponse response) throws Exception {        HttpEntity entity = response.getEntity();        InputStream is = entity.getContent();        // 将输入流转化为byte型        byte[] data = WebService.read(is);        // 转化为字符串        return new String(data, "UTF-8");    }}

 

五、运行效果

  以上工作完成后,只需要讲服务器端发布到本地(附上–mysql-jdbc驱动地址–),安卓端发布到手机,确保局域网内部,ip正确,即可正常访问。

  客户端截图:测试成功

           

  服务器端截图:测试成功

  

 


源码下载 

 




更多相关文章

  1. mybatisplus的坑 insert标签insert into select无参数问题的解决
  2. python起点网月票榜字体反爬案例
  3. 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Debian镜像
  4. 读取android手机流量信息
  5. Android屏幕分辨率正确获取及PX,DPI,DP,SP等的对应关系
  6. 《Android开发从零开始》——25.数据存储(4)
  7. Android系统配置数据库注释(settings.db)
  8. Android中不同应用间实现SharedPreferences数据共享
  9. android 获取唯一标识

随机推荐

  1. AsyncTask的用法
  2. 开源项目之Android(安卓)Afinal框架
  3. Android的构建块的介绍
  4. Android Handler 异步消息处理机制 《第
  5. Android使用cmake+ndk输出原生Log
  6. Android解决输入法自动弹出方法大全
  7. android监听系统联系人修改
  8. Android Studio NDK JNI开发入门记录
  9. Android资料之-EditText中的inputType
  10. 创建Android虚拟设备(AVD)