android客户端+JAVA WEB服务器实现json数据解析

    首先,项目中使用javaweb作为后台服务器,源码地址:服务器和客户端源码地址
接下来进入正题。
   
   一、java web服务器
        
         这里就多说了,不太了解j2ee的请查阅相关书籍。
      
         项目结构如下:
       
        News类定义了之后解析的JSON对象的内容;
        NewsServer则是定义了一个获取最新新闻News的接口;
        NewsServer则是实现了这个接口,定义了获取最新新闻的方法;
        NewsListServlet则是一个实现客户端get和post请求的servlet,用于实现网络请求时的业务逻辑处理,主要返回含有News内容的json字符串;
        jsonnewslist.jsp是一个jsp文件用于测试服务器是否正常运行。
      
      服务器部分就不啰嗦了,直接贴代码和截图
      
  (1)News类
           
 public class News {
	private Integer id;
	private String title;
	private Integer timelength;
	public News(Integer id, String title, Integer timelength) {
		this.id = id;
		this.title = title;
		this.timelength = timelength;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public Integer getTimelength() {
		return timelength;
	}
	public void setTimelength(Integer timelength) {
		this.timelength = timelength;
	}
}
         (2)NewsServer接口
      
public interface NewsServer {
	/*
	 * 获取最新的新闻News
	 */
	public java.util.List<News> getLastNews();

}
          (3)NewsServerBean类 
import java.util.ArrayList;
import java.util.List;

public class NewsServerBean implements NewsServer {

	@Override
	public List<News> getLastNews() {
		// TODO Auto-generated method stub
		List<News> news = new ArrayList<>();
		news.add(new News(10, "吕文健", 20));
		news.add(new News(45, "李昱喜", 10));
		news.add(new News(89, "android is amazing", 50));
		return news;
	}

}
        (4)NewsListServlet类
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet(name="newslist",
            urlPatterns={"/newslist"}
		)//配置Servlet
public class NewsListServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	NewsServerBean serverbean =new NewsServerBean();

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
	   doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		req.setCharacterEncoding("GBK");
		resp.setCharacterEncoding("GBK");//这里设置成gbk防止手机端显示乱码,之前设置为utf-8总是乱码
		List<News> news = serverbean.getLastNews();
		StringBuilder json = new StringBuilder();
		json.append("[");
		for(News news2:news){
			json.append('{').append("\"id\":").append(news2.getId()).append(",");                      
            json.append("\"title\":").append("\""+news2.getTitle()+"\"").append(",");
            json.append("\"timelength\":").append(news2.getTimelength());
            json.append('}').append(",");
		}
		json.deleteCharAt(json.length()-1);//?
		json.append("]");
        req.setAttribute("json", json.toString());
        req.getRequestDispatcher("/jsonnewslist.jsp").forward(req, resp);
	}
}

    (5)jsonnewslist.jsp(在服务端测试服务器是否布置成功)
<%@ page language="java" contentType="text/plain; charset=GBK"
    pageEncoding="GBK"%>
   ${json}
              (6)服务器运行结果

    


      OK,运行成功,服务器解决了,楼主把它打包成war,放在阿里云服务器上,省去了用电脑做服务器的各种麻烦。 接下来进入正题,客户端解析Json


二、android客户端

      客户端部分主要是一个简单的listview显示获取的news,运行结果如下:



接下来,开始贴代码:
    1、布局文件:
    (1)activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="wf.com.getnewsinjson.MainActivity">
<Button
    android:id="@+id/btn_refresh"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:text="刷新"
    />
    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        />
</LinearLayout>
(2)item.xml(ListView中每一个item的布局)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView
        android:id="@+id/title"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_weight="1"
        android:gravity="center"
        />
    <TextView
        android:layout_marginLeft="10dp"
        android:id="@+id/timelength"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="50dp"
        android:gravity="center"
        />
</LinearLayout>
2、主要代码
  (1)、News类(和之前服务器中的一样,用于解析)
   (2)、NewsServer类(用于连接服务器并解析JSON字符串)
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import Util.StreamTool;

/**
 * Created by wangfeng on 2016/12/8.
 */

public class NewsService {
    public static List<News> getJsonLastNews() {
        List<News> list = null;
        InputStream in = null;
                String path = "http://*****";//这里输入自己的服务器地址
                try {
                    list = new ArrayList<>();
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(5000);
                    conn.setRequestMethod("GET");
                    if (conn.getResponseCode()==200){
                        in = conn.getInputStream();
                        list = parseJSON(in);
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    System.out.println("客户端未连接到服务器");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("客户端未连接到服务器");
                }
        return list;
    }
/*
*解析json字符串并返回一个List
*/
    public static List<News>  parseJSON(InputStream in){
        List<News> list = null;
        try {
            list = new ArrayList<>();
//           String str = StreamTool.streamToString(in);
//            System.out.println(str);
            byte[] bytes = StreamTool.stream2Byte(in);//这里用到了StreamTool工具类,自己到CSDN上下载一个,这里是把
                                                       //输入流转化为字节数组
             String str = new String (bytes,"GBK");//因为服务器设置了返回编码为GBK,这里也设置编码方式为GBK	
            System.out.println("解析成功"+str);
            JSONArray jsonArray = new JSONArray(str);//将json字符串转化为JSONArray
            for(int i =0;i< jsonArray.length();i++){
                JSONObject jsonObject = jsonArray.getJSONObject(i);//循环JSONArray获得每一个JSONObject对象
                int id = jsonObject.getInt("id");
                String title = jsonObject.getString("title");
                int timelength = jsonObject.getInt("timelength");
                list.add(new News(id,title,timelength));
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("io","输入流读取错误");
        } catch (JSONException e) {
            e.printStackTrace();
            Log.e("json","json数组转换错误");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
}

    (3)MainActivity类
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity implements Runnable {
    List<HashMap<String,Object>> data;
    private static final int TAG =0X1;//用于Handler中的异步处理标志
    Thread thread = null;//声明线程,用于执行NewsServer中的网络访问
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case TAG:
                    SimpleAdapter simpleAdapter = new SimpleAdapter(MainActivity.this,data,R.layout.item,new String[]{"title","timelength"},new int[]{R.id.title,R.id.timelength});
                    listview.setAdapter(simpleAdapter);
                    break;
            }
        }
    };

    @BindView(R.id.btn_refresh)
    Button btnRefresh;
    @BindView(R.id.listview)
    ListView listview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);//这里使用了ButterKnife组件来初始化组件和绑定id,不懂得自行百度
    }
    
    @OnClick(R.id.btn_refresh)
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_refresh:
                thread = new Thread(this);
                thread.start();
                break;
        }
    }
    
    @Override
    public void run() {
        String length = getResources().getString(R.string.timelength);
        List<News> news = NewsService.getJsonLastNews();//这里必须另起一个线程访问,不能在主线程中访问
         data = new ArrayList<>();
        for(News news1:news){
            HashMap<String,Object> item  = new HashMap<>();
            item.put("id",news1.getId());
            item.put("title",news1.getTitile());
            item.put("timelength",length+": "+news1.getTimelength());
            data.add(item);
        }
        Message msg = new Message();
        msg.what=TAG;
        handler.sendMessage(msg);//通知组件更新界面
    }
}

三、后记
      作为一只菜鸟不得不承认在这次练习中,犯了不少低级错误,比如,服务器端,没有设置返回的编码方式,json字符串忘记加“ ”;在客户端,在非UI线程中更新UI组件,在解析json时没有设置编码方式,在设置请求方式时将GET写成Get,哎,吃一堑长一智。

猜你喜欢

转载自blog.csdn.net/ckq5254/article/details/53540813