其实没什么技术含量,整个工程中最核心的地方就是用到了百度地图提供的lbs接口,通过这个接口访问百度地图提
这次跟门子轩写了个查找附近的人,功能是使用同一软件的人可以将地理位置信息上传到服务器,其他人可通过查找的功能将指定距离内的人的相关信息(包括地理位置信息)查找出来。
其实没什么技术含量,整个工程中最核心的地方就是用到了百度地图提供的lbs接口,通过这个接口访问百度地图提供的数据库,可以实现对表的增删改查等命令,也可以精确的计算gps之间的距离。
工程分为服务器与客户端,客户端可以上传GPS信息,服务器可以通过上传的信息对数据库的GPS进行更新与添加,客户端可以通过发送GPS定位信息让服务器返回附近的人。
因为功能太少,所以就没写图形界面,效果如下:
服务器是用的socket,消息采用的是对象流传输,一共定义了三个消息,更新/添加GPS坐标(MsgSet)、查找附近的人(MsgFind)、服务器返回附近的人的数据(MsgFindRes),还有一个存储信息的People类;
相关代码:
发送get与post请求的HttpTools类:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
package tools; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.util.List; import java.util.Map; public class HttpTools { public static String sendGet(String url,String...params){ String result = ""; BufferedReader in = null; try { String _url = url+"?"; for(String param:params) _url=_url+param+"&"; _url = _url.substring(0, _url.length()-1); URL realUrl = new URL(_url); URLConnection connection = realUrl.openConnection(); connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.connect(); Map<String, List<String>> map = connection.getHeaderFields(); for (String key : map.keySet()) { MLog.DebugLog(key + "--->" + map.get(key)); } in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } }catch(Exception e){ MLog.DebugLogError("发送GET请求出现异常!" + e); e.printStackTrace(); }finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } public static String sendPost(String url, String...params) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { String param = ""; for(String _param:params) param=param+_param+"&"; param = param.substring(0, param.length()-1); URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { MLog.DebugLogError("发送 POST 请求出现异常!"+e); e.printStackTrace(); } //使用finally块来关闭输出流、输入流 finally{ try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(IOException ex){ ex.printStackTrace(); } } return result; } }
用于调试的日志类
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
package tools; public class MLog { private static boolean isDebug = true; public static void DebugLog(String msg){ if(!isDebug) return; System.out.println(msg); } public static void DebugLogError(String msg){ if(!isDebug) return; System.err.println(msg); } }
服务器线程类
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
package server; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.List; import msg.Messages; import msg.MsgFind; import msg.MsgFindRes; import msg.MsgHead; import msg.MsgSet; import msg.People; import org.json.JSONArray; import org.json.JSONObject; import tools.HttpTools; import tools.MLog; public class ServerThread extends Thread { private Socket client; private ObjectInputStream ois; private ObjectOutputStream oos; private boolean isConnect = true; public ServerThread(Socket client) { // TODO Auto-generated constructor stub this.client = client; try { ois = new ObjectInputStream(client.getInputStream()); oos = new ObjectOutputStream(client.getOutputStream()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void run() { // TODO Auto-generated method stub super.run(); while(isConnect){ try { Object obj = ois.readObject(); dealMsg(obj); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); isConnect = false; } } } private void dealMsg(Object obj) { // TODO Auto-generated method stub MsgHead mh = null; try{ mh = (MsgHead)obj; }catch(Exception e){ MLog.DebugLogError("收到了错误的包:"+obj.getClass().getName()); return; } switch (mh.getType()) { case Messages.FindPeople: findPeople((MsgFind)mh); break; case Messages.SetPeople: setPeople((MsgSet)mh); break; default: MLog.DebugLogError("未知类型:"+mh.getType()); break; } } private void setPeople(MsgSet obj) { // TODO Auto-generated method stub String result = HttpTools.sendGet(ServerMessage.FindUrl2,"ak="+ServerMessage.LbsKey, "geotable_id="+ServerMessage.id, "name="+obj.getName()); System.err.println(result); JSONObject json = new JSONObject(result); try{ JSONArray peoples = json.getJSONArray("pois"); }catch(Exception e){ HttpTools.sendPost(ServerMessage.createUrl,"ak="+ServerMessage.LbsKey, "geotable_id="+ServerMessage.id, "longitude="+obj.getLongitude(), "latitude="+obj.getLatitude(), "coord_type=1", "name="+obj.getName()); return; } HttpTools.sendPost(ServerMessage.updateUrl, "ak="+ServerMessage.LbsKey, "geotable_id="+ServerMessage.id, "coord_type=1", "name="+obj.getName(), "longitude="+obj.getLongitude(), "latitude="+obj.getLatitude()); } private void findPeople(MsgFind obj) { // TODO Auto-generated method stub String result=HttpTools.sendGet(ServerMessage.FindUrl,"ak="+ServerMessage.LbsKey, "geotable_id="+ServerMessage.id, "location="+obj.getLongitude()+","+obj.getLatitude(), "radius="+obj.getDistance(), "sortby=distance:1"); JSONObject json = new JSONObject(result); JSONArray peoples = json.getJSONArray("contents"); MsgFindRes mfr = new MsgFindRes(); List list = mfr.getPeoples(); for(int i = 0;i<peoples.length();i++){ JSONObject jo = peoples.getJSONObject(i); People p = new People(); JSONArray ja = jo.getJSONArray("location"); /*String location = jo.getString("location"); location = location.replaceAll("[", ""); location = location.replaceAll("]", ""); location = location.replaceAll(" ", ""); String str[] = location.split(","); p.setLongitude(Double.parseDouble(str[0])); p.setLatitude(Double.parseDouble(str[1]));*/ p.setLongitude(ja.getDouble(0)); p.setLatitude(ja.getDouble(1)); p.setName(jo.getString("name")); p.setDirection(jo.getString("direction")); p.setDistance(jo.getInt("distance")); p.setAddress(jo.getString("province")+jo.getString("city")+jo.getString("district")); list.add(p); } try { oos.writeObject(mfr); oos.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
服务器类
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
package server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Server extends Thread{ ServerSocket ss; ExecutorService es = Executors.newCachedThreadPool(); @Override public void run() { // TODO Auto-generated method stub super.run(); try { ss = new ServerSocket(ServerMessage.port); while(true){ Socket socket = ss.accept(); es.execute(new ServerThread(socket)); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
客户端类
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
package client; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.UnknownHostException; import msg.Messages; import msg.MsgFindRes; import msg.MsgHead; import msg.People; import server.ServerMessage; import tools.MLog; public class Client extends Thread{ private static Client client; Socket socket; ObjectOutputStream oos; ObjectInputStream ois; boolean isConnect = true; private Client(){init();} public static Client getInstance(){ client = client==null?new Client():client; return client; } public void sendMsg(MsgHead mh) throws IOException{ oos.writeObject(mh); oos.flush(); } private void init() { // TODO Auto-generated method stub try { Socket socket = new Socket(ServerMessage.ip, ServerMessage.port); oos = new ObjectOutputStream(socket.getOutputStream()); ois = new ObjectInputStream(socket.getInputStream()); } catch (UnknownHostException e) { // TODO Auto-generated catch block isConnect = false; e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block isConnect = false; e.printStackTrace(); } this.start(); } public void run() { while(isConnect){ try { Object obj = ois.readObject(); dealMsg(obj); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); isConnect = false; } } } private void dealMsg(Object obj) { // TODO Auto-generated method stub MsgHead mh = null; try{ mh = (MsgHead)obj; }catch(Exception e){ MLog.DebugLogError("类型转换异常:"+obj.getClass().getName()); return; } switch (mh.getType()) { case Messages.FindRes: FindRes((MsgFindRes)mh); break; default: break; } } private void FindRes(MsgFindRes mh) { // TODO Auto-generated method stub int n = mh.getPeoples().size(); MLog.DebugLog("共找到"+n+"个附近的人"); for(People p : mh.getPeoples()){ String str = "姓名:"+p.getName()+"\t地址:"+p.getAddress()+"\t距离:"+p.getDistance()+"米\t方向:"+p.getDirection()+"\t经纬度:"+p.getLongitude()+","+p.getLatitude(); MLog.DebugLog(str); } }; }
消息类与一些常量就不贴了。
因为调用百度地图接口的时候需要收到json数据,所以还使用了org.json包。
没什么具体约定的规范,在编写的时候想起来缺少什么就现往里添加,及时补充。
从下午1点做到4点多钟。
心得与体会:
很多东西 可以直接利用现成的接口,因为自己写的并不一定比那些已经被验证了无数次的代码效果要好。很多事情还得现从实际生活中挖掘,加上之前已经有过类似的网络编程经验,所以做起来还算是得心应手。