关于android通过servlet访问MySql数据库的问题(附带简单的JSON使用)

来源:互联网 发布:一键无痕偷窥软件 编辑:程序博客网 时间:2024/06/07 06:15

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~准备工作~~~~~~~~~~~~~~~~~~~~~~~

   。tomcat编译servlet要用到servlet.api.jar包,需要存放于C:\ProgramFiles\Java\jdk1.6.0_07\jre\lib\ext中或者配置classpath。

 

   二。操作MySQL需要下载驱动mm.mysql,mysql-connector-java-3.1.14-bin.jar存放于项目的web-inf/lib目录及tomcat的lib目录下。

 

   三。Android程序访问网络需要在AndroidManifest.xml中声明权限

     <uses-permissionandroid:name=”android.permission.INTERNET”></uses-permission>

 

   四。3.0以上系统需要在onCreat方法中写下以下语句,否则会出现android.os.NetworkOnMainThreadException异常。

    

[html] view plain copy
print?
  1. StrictMode.setThreadPolicy(newStrictMode.ThreadPolicy.Builder()  
  2.   
  3.                          .detectDiskReads().detectDiskWrites().detectNetwork()               
  4.   
  5.                          .penaltyLog().build());                            
  6.   
  7. StrictMode.setVmPolicy(newStrictMode.VmPolicy.Builder()                         
  8.   
  9.                          .detectLeakedSqlLiteObjects().detectLeakedClosableObjects()      
  10.   
  11.                          .penaltyLog().penaltyDeath().build());          
   StrictMode.setThreadPolicy(newStrictMode.ThreadPolicy.Builder()                            .detectDiskReads().detectDiskWrites().detectNetwork()                                         .penaltyLog().build());                             StrictMode.setVmPolicy(newStrictMode.VmPolicy.Builder()                                                   .detectLeakedSqlLiteObjects().detectLeakedClosableObjects()                                .penaltyLog().penaltyDeath().build());        

                                                                       

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~OK,可以开始了~~~~~~~~~~~~~~~~~~~

 

一。接收端android简易程序

[html] view plain copy
print?
  1. public class Abc_clientActivity extendsActivity {  
  2.   
  3.        /**Called when the activity is first created. */  
  4.   
  5.        Button mButton;  
  6.   
  7.        TextView mTextView;  
  8.   
  9.        String content;  
  10.   
  11.        @Override  
  12.   
  13.        public void onCreate(Bundle savedInstanceState) {  
  14.   
  15.               super.onCreate(savedInstanceState);  
  16.   
  17.               setContentView(R.layout.main);  
  18.   
  19.               mButton= (Button) findViewById(R.id.button1);  
  20.   
  21.               mTextView= (TextView) findViewById(R.id.textView1);  
  22.   
  23.               a();  
  24.   
  25.               mButton.setOnClickListener(new Button.OnClickListener() {  
  26.   
  27.                      @Override  
  28.   
  29.                      public void onClick(View arg0) {  
  30.   
  31.                             try{  
  32.   
  33.                                    contentConnecting(); //获取返回值  
  34.   
  35.                             }catch (IOException e) {  
  36.   
  37.                                    e.printStackTrace();  
  38.   
  39.                             }  
  40.   
  41.                             mTextView.setText(content);   //在TextView中显示  
  42.   
  43.                      }  
  44.   
  45.               });  
  46.   
  47.        }  
  48.   
  49.        private void a() {  
  50.   
  51.               StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()  
  52.   
  53.                             .detectDiskReads().detectDiskWrites().detectNetwork()              
  54.   
  55.                             .penaltyLog().build());                               
  56.   
  57.               StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                          
  58.   
  59.                             .detectLeakedSqlLiteObjects().detectLeakedClosableObjects()    
  60.   
  61.                             .penaltyLog().penaltyDeath().build());                         
  62.   
  63.        }  
  64.   
  65.        protected String Connecting() throws ParseException, IOException {  
  66.   
  67. //这个路径最后会详细说明  
  68.   
  69.               String url1 =“http://10.81.36.187:8080/orderdishes/orderdishes_servlet”;     
  70.   
  71.               String url2 = “username=” + “a”;  
  72.   
  73.               String url = url1 + ”?” + url2;       
  74.   
  75.   //即相当于http://10.81.36.187:8080/orderdishes/orderdishes_servlet?username=“a”,其中的//username对应”a”,后面会用到  
  76.   
  77.               String result = “”;  
  78.   
  79.               System.out.println(“1”);  
  80.   
  81.               HttpGet request = new HttpGet(url);     //调用servlet的doget方法  
  82.   
  83.               System.out.println(“2”);  
  84.   
  85.                //在这里执行请求,访问url,并获取响应  
  86.   
  87.               HttpResponse response = new DefaultHttpClient().execute(request);   
  88.   
  89.               System.out.println(“3”);  
  90.   
  91. //获取返回码,等于200即表示连接成功,并获得响应  
  92.   
  93.               if(response.getStatusLine().getStatusCode() == 200) {  
  94.   
  95.                      System.out.println(“4”);  
  96.   
  97.                      resultEntityUtils.toString(response.getEntity());  //获取响应中的数据  
  98.   
  99.                      System.out.println(“result”+ result);  
  100.   
  101.               }else {  
  102.   
  103.                      System.out.println(“连接失败”);  
  104.   
  105.               }  
  106.   
  107.               return result;  
  108.   
  109. }  
  110.   
  111. }  
public class Abc_clientActivity extendsActivity {       /**Called when the activity is first created. */       Button mButton;       TextView mTextView;       String content;       @Override       public void onCreate(Bundle savedInstanceState) {              super.onCreate(savedInstanceState);              setContentView(R.layout.main);              mButton= (Button) findViewById(R.id.button1);              mTextView= (TextView) findViewById(R.id.textView1);              a();              mButton.setOnClickListener(new Button.OnClickListener() {                     @Override                     public void onClick(View arg0) {                            try{                                   content= Connecting(); //获取返回值                            }catch (IOException e) {                                   e.printStackTrace();                            }                            mTextView.setText(content);   //在TextView中显示                     }              });       }       private void a() {              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                            .detectDiskReads().detectDiskWrites().detectNetwork()                                        .penaltyLog().build());                                           StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                                    .detectLeakedSqlLiteObjects().detectLeakedClosableObjects()                              .penaltyLog().penaltyDeath().build());                              }       protected String Connecting() throws ParseException, IOException {//这个路径最后会详细说明              String url1 ="http://10.81.36.187:8080/orderdishes/orderdishes_servlet";                 String url2 = "username=" + "a";              String url = url1 + "?" + url2;       //即相当于http://10.81.36.187:8080/orderdishes/orderdishes_servlet?username="a",其中的//username对应"a",后面会用到              String result = "";              System.out.println("1");              HttpGet request = new HttpGet(url);     //调用servlet的doget方法              System.out.println("2");               //在这里执行请求,访问url,并获取响应              HttpResponse response = new DefaultHttpClient().execute(request);               System.out.println("3");//获取返回码,等于200即表示连接成功,并获得响应              if(response.getStatusLine().getStatusCode() == 200) {                     System.out.println("4");                     result= EntityUtils.toString(response.getEntity());  //获取响应中的数据                     System.out.println("result"+ result);              }else {                     System.out.println("连接失败");              }              return result;}}

 

二、servlet类(不是在一个工程中写的,所以没有包名,这里的文件名是orderdishes_servlet.java)

[html] view plain copy
print?
  1. import java.io.IOException;  
  2.   
  3. import java.io.PrintWriter;  
  4.   
  5. import java.sql.Connection;  
  6.   
  7. import java.sql.DriverManager;  
  8.   
  9. import java.sql.ResultSet;  
  10.   
  11. import java.sql.SQLException;  
  12.   
  13. import java.sql.Statement;  
  14.   
  15.    
  16.   
  17. import javax.servlet.ServletException;  
  18.   
  19. import javax.servlet.annotation.WebServlet;  
  20.   
  21. import javax.servlet.http.HttpServlet;  
  22.   
  23. importjavax.servlet.http.HttpServletRequest;  
  24.   
  25. importjavax.servlet.http.HttpServletResponse;  
  26.   
  27.    
  28.   
  29. public class orderdishes_servlet extends HttpServlet {  
  30.   
  31.        private static final long serialVersionUID = 1L;  
  32.   
  33.        /**  
  34.   
  35.         * @see HttpServlet#HttpServlet()  
  36.   
  37.         */  
  38.   
  39.        protected void doGet(HttpServletRequest request,             //只使用doGet方法  
  40.   
  41.        HttpServletResponse response)  {        
  42.   
  43.        String name = null;  
  44.   
  45. try {  
  46.   
  47. //获取请求url中携带的参数,及之前的username所对应的”a”  
  48.   
  49. name = newString(request.getParameter(“username”).getBytes(  
  50.   
  51.                             “ISO-8859-1”),”UTF-8”);     
  52.   
  53. //mm.mysql的class名为org.gjt.mm.mysql.Driver,登记时必须写成如下格式  
  54.   
  55.        Class.forName(“org.gjt.mm.mysql.Driver”).newInstance();  
  56.   
  57.   
  58. //其中db为MySql数据库的名字,root为数据库的账号,password为密码,同时使用//useUnicode,characterEncoding,能解决数据库输出时的中文问题  
  59.   
  60.        Connection C = DriverManager.getConnection(“jdbc:mysql://localhost/db?user=root&password=123&useUnicode=true&characterEncoding=8859_1“);  
  61.   
  62.   
  63. //代码中使用了absolute,ResultSet.TYPE_SCROOL_SENSITIVE等的目的是为了测试//mm.mysql是否符合jdbc 2.0的规范,虽然我也不懂具体用意  
  64.   
  65.        Statement stateC.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);  
  66.   
  67. //将查询的结果放在result中,test为表名  
  68.   
  69.        ResultSet result=state.executeQuery(“select * from test wherename=“+”\”“+name+”\”“);  
  70.   
  71.        if(result!=null){  
  72.   
  73.           response.setContentType(“text/html;charset=UTF-8”);//这句必须放在PrintWriter//out=response.getWriter();前面,不然输出中文依然为乱码。  
  74.   
  75.           PrintWriter out = response.getWriter();  
  76.   
  77.           while(result.next()){  
  78.   
  79.           out.print(“用户名:”+name+”的账号密码为:”+result.getString(“name”)+”“+result.getString(“password”));  
  80.   
  81.           }  
  82.   
  83.        }else{  
  84.   
  85.           PrintWriter out = response.getWriter();  
  86.   
  87.           out.print(“用户名不存在”);      //这个是响应之后返回的数据  
  88.   
  89.        }  
  90.                   
  91. } catch (InstantiationException e) {  
  92.   
  93.        e.printStackTrace();  
  94.   
  95. } catch (IllegalAccessException e) {  
  96.   
  97.        e.printStackTrace();  
  98.   
  99. } catch (ClassNotFoundException e) {  
  100.   
  101.        e.printStackTrace();  
  102.   
  103. } catch (IOException e) {  
  104.   
  105.        e.printStackTrace();  
  106.   
  107. } catch (SQLException e) {  
  108.   
  109.        e.printStackTrace();  
  110.   
  111. }  
  112.   
  113.        }  
import java.io.IOException;import java.io.PrintWriter;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;public class orderdishes_servlet extends HttpServlet {       private static final long serialVersionUID = 1L;       /**        * @see HttpServlet#HttpServlet()        */       protected void doGet(HttpServletRequest request,             //只使用doGet方法       HttpServletResponse response)  {             String name = null;try {//获取请求url中携带的参数,及之前的username所对应的"a"name = newString(request.getParameter("username").getBytes(                            "ISO-8859-1"),"UTF-8");   //mm.mysql的class名为org.gjt.mm.mysql.Driver,登记时必须写成如下格式       Class.forName("org.gjt.mm.mysql.Driver").newInstance();//其中db为MySql数据库的名字,root为数据库的账号,password为密码,同时使用//useUnicode,characterEncoding,能解决数据库输出时的中文问题       Connection C = DriverManager.getConnection("jdbc:mysql://localhost/db?user=root&password=123&useUnicode=true&characterEncoding=8859_1");//代码中使用了absolute,ResultSet.TYPE_SCROOL_SENSITIVE等的目的是为了测试//mm.mysql是否符合jdbc 2.0的规范,虽然我也不懂具体用意       Statement state= C.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);//将查询的结果放在result中,test为表名       ResultSet result=state.executeQuery("select * from test wherename="+"\""+name+"\"");       if(result!=null){          response.setContentType("text/html;charset=UTF-8");//这句必须放在PrintWriter//out=response.getWriter();前面,不然输出中文依然为乱码。          PrintWriter out = response.getWriter();          while(result.next()){          out.print("用户名:"+name+"的账号密码为:"+result.getString("name")+""+result.getString("password"));          }       }else{          PrintWriter out = response.getWriter();          out.print("用户名不存在");      //这个是响应之后返回的数据       }} catch (InstantiationException e) {       e.printStackTrace();} catch (IllegalAccessException e) {       e.printStackTrace();} catch (ClassNotFoundException e) {       e.printStackTrace();} catch (IOException e) {       e.printStackTrace();} catch (SQLException e) {       e.printStackTrace();}       }

三。tomcat中的配置

1.在tomcat根目录下建立以下文件夹

 E:\Tomcat 7.0\webapps\orderdishes

 

2.在orderdishes中建立WEB-INF文件夹,里面建个classes文件夹

 

3.将之前的orderdishes_servlet.java通过javac命令编译成orderdishes_servlet.class放在classes文件夹中

 

4.然后我们需要定义web.xml文件,这个可以在E:\Tomcat 7.0\webapps\ROOT\WEB-INF下copy一个,然后加入以下语句

 

<servlet>

<servlet-name>orderdishes_servlet</servlet-name>    //servlet名称

<servlet-class>orderdishes_servlet</servlet-class>   //servlet指向的类文件

</servlet>

<servlet-mapping>

<servlet-name>orderdishes_servlet</servlet-name>

<url-pattern>/orderdishes_servlet</url-pattern>           //这个是定义web访问时servlet的相对路径

 

如此,我们之前定义的url格式就是http://10.81.36.187:8080/orderdishes/orderdishes_servlet,orderdishes是指servlet所在的文件夹名字,/orderdishes_servlet 就是上面定义的相对路径。

如果写成

<url-pattern>servlet/orderdishes_servlet</url-pattern> 

我们之前定义的url格式就要变成http://10.81.36.187:8080/orderdishes/servlet/orderdishes_servlet了

 

四。在MySQL中新建数据库db,表名为test(MySQl的密码为123 – 就是启动MySQL时需要输入的密码,这个是安装时就需要设置的)

 name    password

   a               123

   b               234

因为之前我们的查询语句是select *  from test where name=”+”\”“+name+”\”,name=”a”所以TextView中会显示

 

用户名:a 的账号密码为:a 123

 

——————————–以上我们只获取了单条数据,下面是多条的方法————————

复习了昨天学习的内容,然后开始修改源程序,目前进度是修改获取分类列表数据 ,发现一个问题,就是昨天在例子中返回的只是一条数据,可以正常显示,然后今天是返回多条数据,会出现以下情况:

据测试, servlet中执行以下语句

PrintWriter out = response.getWriter();

out.print(“a ”);

out.print(“b”);

在返回的数据中通过

String result = EntityUtils.toString(response.getEntity());

获得的结果是 result=”a b” ,这个结果是一次性的,意思就是执行一次就获得了这个结果,说明数据不是一条 一条发送过来的

 

猜测的结果是:  servlet中是执行完所有out.print(“”);将数据组装完,放在response中然后在发送回去的。

所以这样我们就不能实现返回所有分类列表数据,想到的一种可能是在客户端,通过String[] Accept = result.split(“,”);分割的方法获得数据,不过这样感觉不好。

后来发现使用JSON可能是个不错的选择,然后就开始学习JSON的使用,经过试验,最后成功了. 我们的 方法就是在servlet类中,通过以下语句

[html] view plain copy
print?
  1. StringBuilder responseResult=new StringBuilder();  
  2.   
  3. ResultSet result=state.executeQuery(“select  * from test”);  
  4.   
  5. response.setContentType(“text/html;charset=UTF-8”);  
  6.   
  7. PrintWriter out = response.getWriter();  
  8.   
  9. responseResult.append(“[“);  
  10.   
  11. while(result.next()){  
  12.   
  13.   responseResult.append(“{“+”\”SortName\”:”+result.getString(“sortname”)+”}”+”,”);  //重点,下有解释  
  14.   
  15. }  
  16.   
  17. responseResult.deleteCharAt(responseResult.length()-1);//删除最后的”,”号  
  18.   
  19. responseResult.append(“]”);  
  20.   
  21. out.print(responseResult.toString());  
StringBuilder responseResult=new StringBuilder();ResultSet result=state.executeQuery("select  * from test");response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();responseResult.append("[");while(result.next()){  responseResult.append("{"+"\"SortName\":"+result.getString("sortname")+"}"+",");  //重点,下有解释}responseResult.deleteCharAt(responseResult.length()-1);//删除最后的”,”号responseResult.append("]");out.print(responseResult.toString());

也就是说,通过以上语句,将查询出的结果,组装成JSONArray类型,然后以String字符串型返回。

接着在客户端进行解析就可以(其中的result即是在数据请求时,通过以下语句获得的String字符串

[html] view plain copy
print?
  1. resultEntityUtils.toString(response.getEntity());  //获取响应中的数据),  
  2. 字符串转换成JSON数组,然后通过解析,获取对应的每条数据。方法如下:  
        result= EntityUtils.toString(response.getEntity());  //获取响应中的数据),在这里我们先将此字符串转换成JSON数组,然后通过解析,获取对应的每条数据。方法如下:

[html] view plain copy
print?
  1. List<DishInfo> mListDataForSort=new ArrayList<DishInfo>();  
  2.   
  3.         mJsonArray = new JSONArray(result);     
  4.   
  5.        for(int i=0;i<mJsonArray.length();i++){  
  6.   
  7.            JSONObject  mJsonObject=(JSONObject)mJsonArray.opt(i);  
  8.   
  9.            String sortname=mJsonObject.getString(“SortName”);  
  10.   
  11.            DishInfo item=new DishInfo();  
  12.   
  13.            item.setDishSort(sortname);  
  14.   
  15.            mListDataForSort.add(item);  
  16.   
  17.         }  
List<DishInfo> mListDataForSort=new ArrayList<DishInfo>();        mJsonArray = new JSONArray(result);          for(int i=0;i<mJsonArray.length();i++){           JSONObject  mJsonObject=(JSONObject)mJsonArray.opt(i);           String sortname=mJsonObject.getString("SortName");           DishInfo item=new DishInfo();           item.setDishSort(sortname);           mListDataForSort.add(item);        }


当然这只是一种简单的JSON的使用,后续会加入图片的处理以及混合的JSONObject和JSONArray的数据解析。

注意:

responseResult.append(“{“+”\”SortName\”:”+result.getString(“sortname”)+”}”+”,”);

 

如果要封装的数据是其他类型,比如byte[]和http://……  类的,一定要这么写

responseResult.append(“{“+”\”SortName\”:”+”\”“+byte[]+”\”“+”}”+”,”);

 

没错,需要加转义字符,为数据两边 加上 双引号” “,这样就不会出现 解析的时候提示 非法字符的错误了。

 

好吧,这只是篇备注文章,JSON具体的使用方法可以 百度= =

 


0 0
原创粉丝点击