Android使用json和Http实现与服务器的简单交互
自己学习android与服务器数据交互时,在网上看了很多例子,要么是例子代码太多没耐心看,要么是代码没发全,对于一个白手来说理解起来有困难,所以我在自己成功后决定写一篇博客来讲解android与服务器数据交互。由于刚学,解释很多时我自己的理解,有可能有错误,大家看完后有助于自己的理解就好必要太较真。
代码与解释如下:
服务器端(jsp+java+tomcat):
(1)servlet(Service .java)
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.mysql.jdbc.Connection; import com.sun.org.apache.xpath.internal.operations.Bool; import DBSql.DBUtil; import DBSql.Write; import Student.Serv; import Student.Tools; @WebServlet("/Service") public class Service extends HttpServlet { private static final long serialVersionUID = 1L; //Serv类用于模拟一些进行交互的数据 private Serv service1 = new Serv(); /** * @see HttpServlet#HttpServlet() */ public Service() { super(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //获取值 String username = request.getParameter("Message"); String password = request.getParameter("password"); Student student=new Student(); student.setName("wang"); student.setNum("2016"); //System.out.print(Write.panduan(username, password)); if("123".equals(username)&&"789".equals(password)){//账号:123 密码:789 System.out.print(Tools.createJsonString("listMap", service1.getListMaps())); response.setContentType("text/html;charset=UTF-8"); response.getWriter().print("success"); }else{ response.setContentType("text/html;charset=UTF-8"); //密码错误后,原来是返回false,现在为了测试json,我将下面换成了一个json数组 response.getWriter().print(Tools.createJsonString("listMap", service1.getListString())); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } }
(2)Serv.java用于生成一些json数据,以供servlert调用
以下代码中有4个函数生成不同的json数据,本例中Service .java中使用的是第三个函数
package Student; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Serv { public Serv() { // TODO Auto-generated constructor stub } //json中值使用""引起来的所以下面用转义字符\"来将数据包起来,若无\"同样可以传过去但是jsonArray中无法解析 public Person getPerson(){ Person person = new Person(23, "\"AHuier\"", "\"XIAMEN\""); return person; } //json中值使用""引起来的所以下面用转义字符\"来将数据包起来,若无\"同样可以传过去但是jsonArray中无法解析 public List<Person> getListPerson(){ List<Person> list = new ArrayList<Person>(); Person person1 = new Person(1001, "\"AHuier1\"", "\"Beijing\""); Person person2 = new Person(1002, "\"AHuier2\"", "\"shenzheng\""); list.add(person1); list.add(person2); return list; } //json中值使用""引起来的所以下面用转义字符\"来将数据包起来,若无\"同样可以传过去但是jsonArray中无法解析 public List<String> getListString(){ List<String> list = new ArrayList<String>(); list.add("\"Hello\""); list.add("\"World\""); list.add("\"AHuier\""); return list; } //json中值使用""引起来的所以下面用转义字符\"来将数据包起来,若无\"同样可以传过去但是jsonArray中无法解析 public List<Map<String, Object>> getListMaps(){ List<Map<String, Object>> listMap = new ArrayList<Map<String,Object>>(); Map<String, Object> map1 = new HashMap<String, Object>(); map1.put("color", "\"red\""); map1.put("id", 01); map1.put("name", "\"Polu\""); listMap.add(map1); Map<String, Object> map2 = new HashMap<String, Object>(); map2.put("id", 07); map2.put("color", "\"green\""); map2.put("name", "\"Zark\""); listMap.add(map2); return listMap; } }
此时服务器端已经写完了,下面我们使用安卓客户端访问这个服务器来实现数据交互
服务器端(jsp+java+tomcat):
首先添加网络依赖
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
然后导入包
这些包是与json有关的,一下是包的下载链接
链接:https://pan.baidu.com/s/1_3KN2NQ7DihzgNedfHQDyA
提取码:derr
(1)NetUtil类来实现与服务器的交互函数
package com.example.myapplication; /** * Created by 海绵宝宝 on 2019/4/20. */ import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class NetUtil { /** * 发送http请求 * @param username * @param password */ public static String loginOfGet(String username,String password){ HttpURLConnection conn=null; //一下为自己的服务器ip,10.0.2.2:8081是本机的ip,android中本机ip不是localhost String myurl = "http://10.0.2.2:8081/ajaxchuazhi/Service?"; try { //拼接字符串向服务器传值 String data="Message="+username+"&password="+password; URL url=new URL(myurl+data); conn=(HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(10000); conn.setReadTimeout(5000); conn.connect(); int code=conn.getResponseCode(); if(code==200){ //接受数据 InputStream is=conn.getInputStream(); String state=getStringFromInputStream(is); return state; } } catch (Exception e) { e.printStackTrace(); }finally{ if(conn!=null){ conn.disconnect(); } } return null; } /** * 根据输入流返回一个字符串 * @param is * @throws Exception */ //接受数据的函数 private static String getStringFromInputStream(InputStream is) throws Exception{ ByteArrayOutputStream baos=new ByteArrayOutputStream(); byte[] buff=new byte[1024]; int len=-1; while((len=is.read(buff))!=-1){ baos.write(buff, 0, len); } is.close(); String mes=baos.toString(); baos.close(); return mes; } }
MianActivity.java代码
package com.example.myapplication; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import android.widget.EditText; import net.sf.json.JSONObject; import org.json.JSONArray; public class MainActivity extends AppCompatActivity { public Button bt; public EditText et_username; public EditText et_password; public TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt = (Button)findViewById(R.id.button); tv = (TextView)findViewById(R.id.textView); et_username = (EditText)findViewById(R.id.username); et_password = (EditText)findViewById(R.id.password); //按钮设置点击事件 bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //主线程无法访问网络,开启一个新线程 new Thread(new Runnable() { //获取账号密码 final String username = et_username.getText().toString(); final String password = et_password.getText().toString(); @Override public void run() { //访问网络要在子线程中实现,使用get取数 final String state=NetUtil.loginOfGet(username,password); //执行在主线程上(返回主线程显示) runOnUiThread(new Runnable() { public void run() { //就是在主线程上操作,弹出结果 if(state.equals("success")){ tv.setText(state); }else{ try { //将数据转化成JSONObject JSONObject jsonObject = JSONObject.fromObject(state); //将JSONObject中数据放入JSONArray数组中 net.sf.json.JSONArray family = jsonObject.getJSONArray("listMap"); for (int i = 0; i < family.size(); i++) { //提取出family中的所有 String s1 = (String) family.get(i); System.out.println("currentFamily:" + s1); } }catch (Exception e){ e.printStackTrace(); } Toast.makeText(MainActivity.this, state ,Toast.LENGTH_LONG).show(); } } }); } }).start(); } }); } }
(3)布局文件中的代码
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:id="@+id/textView" android:layout_marginBottom="49dp" android:layout_above="@+id/button" android:layout_centerHorizontal="true" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="confirm" tools:layout_editor_absoluteX="148dp" tools:layout_editor_absoluteY="153dp" android:layout_marginBottom="100dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> <EditText android:id="@+id/username" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="72dp" android:ems="10" android:inputType="textPersonName" android:hint="username" /> <EditText android:id="@+id/password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" android:hint="password" android:layout_below="@+id/username" android:layout_alignLeft="@+id/username" android:layout_alignStart="@+id/username" android:layout_marginTop="58dp" /> </RelativeLayout>
此时代码就完成了
可以看到json数据已经接收到
json的解析