这篇文章中贴出china的所有城市及其具体的管辖范围及所属情况,可复制保存为city.json文件。
下面将来对城市代码的JSON文件进行获取与查询:
获取主类:CityCode.java
package com.eabour.weather;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.eabour.tool.HttpVisit;
import com.eabour.tool.LogUtil;
public class CityCode {
private final String BASE_URL="http://m.weather.com.cn/data5/city";
private final String SUFFIX=".xml";
private final int threadsSize=10;
private int[] status=new int[threadsSize];
public CityCode(){}
private synchronized int getStatus(){
for(int i=0 ; i
if(status[i] == 0) {
status[i]=-1;
return i;
}
}
return -1;
}
private synchronized void setStatus(int i){
if(i > 0 && i < status.length){
status[i]=0;
}
}
public Map getCityZone(String citycode){
return getCode(BASE_URL + citycode + SUFFIX);
}
public Map getProvinceList(){
return getCode(BASE_URL + SUFFIX);
}
public Map getCityList(boolean threads){
Map pro_map=getProvinceList();
if(threads) return getCodeMulti(pro_map);
Map map=new HashMap();
Set keys=pro_map.keySet();
for(String key : keys){
Map t_map=getCode(BASE_URL + key + SUFFIX);
if(t_map != null) map.putAll(t_map);
}
return map;
}
public Map getDistrictList(boolean threads){
Map city_map=getCityList(threads);
if(threads) return getCodeMulti(city_map);
Map map=new HashMap();
Set citys=city_map.keySet();
for(String city : citys){
Map t_map=getCode(BASE_URL + city + SUFFIX);
if(t_map != null) map.putAll(t_map);
}
return map;
}
public Map getAreaCodeList(boolean threads){
Map district_map=getDistrictList(threads);
if(threads) return getCodeMulti(district_map);
Map map=new HashMap();
Set districts=district_map.keySet();
for(String district : districts){
Map t_map=getCode(BASE_URL + district + SUFFIX);
if(t_map != null) map.putAll(t_map);
}
return map;
}
private Map getCode(String url){
Map map=new HashMap();
String content=new HttpVisit().httpGet(url);
if(content == null) return map;
content = content.replace('\n', '\0').trim();
String pro_1[]=content.split(",");
for(String tmp : pro_1){
String pro_2[]=tmp.split("\\|");
if(pro_2.length == 2 && !"".equals(pro_2[0])){
map.put(pro_2[0], pro_2[1]);
}
}
return map;
}
private Map getCodeMulti(Map argMap){
Map pro_map=argMap;
ArrayList> list=new ArrayList>(threadsSize);
for(int i=0; i
list.add(new HashMap());
}
Map map=new HashMap();
Set keys=pro_map.keySet();
for(String key : keys){
while(true) {
int index=getStatus();
if(index > -1) {
new Thread(new HttpThread(BASE_URL + key + SUFFIX, list.get(index), index)).start();
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
LogUtil.logWarn(CityCode.class, "getCityListNulti", e.toString());
}
}
}
for(Map tmap : list){
if(tmap != null) map.putAll(tmap);
}
return map;
}
private class HttpThread implements Runnable{
private String url;
private Map map;
private int flag;
public HttpThread(String url, Map map, int flag){
this.url=url;
this.map=map;
this.flag=flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
map.putAll(getCode(url));
setStatus(flag);
}
}
}
其中,HttpVisit类是对http访问的封装,LogUtil类是记录日志的,可不要。其中,方法名中含Multi的是表示采用多线程来获取,因为获取的时候非常慢,而且个别出错。
以下是HttpVisit类:
package com.eabour.tool;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpVisit {
String multipart_form_data = "multipart/form-data";
String twoHyphens = "----------------------------";
String boundary = "7dd1721b6034a"; // 数据分隔符
String lineEnd = System.getProperty("line.separator"); // The value is "\r\n" in Windows.
private HttpURLConnection getConnection(String url ,String method)
throws IOException{
URL u=new URL(url);
HttpURLConnection conn=(HttpURLConnection) u.openConnection();
conn.setRequestMethod(method);
conn.setDoInput(true);
conn.setDoOutput(true);
return conn;
}
private String httpVisit(String url, String method, String content){
try {
HttpURLConnection conn=getConnection(url, method);
if("POST".equals(method) && content != null ){
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(content);
out.flush();
out.close();
}
else if("GET".equals(method)){
conn.connect();
}
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line,result="";
while ((line = in.readLine())!= null)
{
result += "\n" + line;
}
return result;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
LogUtil.logWarn(getClass(), "httpVisit",e.toString() + "URL: " + url);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
LogUtil.logWarn(getClass(), "httpVisit",e.toString() + "URL: " + url);
}
return null;
}
public String httpGet(String url){
return httpVisit(url, "GET", null);
}
public String httpPost(String url, String content){
return httpVisit(url, "POST", content);
}
public String httpUpload(String url, String f){
try {
File file = new File(f);
HttpURLConnection conn=getConnection(url, "POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)");
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.setRequestProperty("Cache-Control", "no-cache");
//conn.setRequestProperty("Content-Length", 188 + file.length() + "");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ twoHyphens + boundary +"");
//conn.setUseCaches(false);
StringBuilder split = new StringBuilder();
split.append(twoHyphens + boundary + lineEnd);
split.append("Content-Disposition: form-data; name=\"media\"; filename=\"" + file.getName()+ "\"" + lineEnd);
split.append("Content-Type: image/jpeg" + lineEnd);
split.append(lineEnd);
OutputStream out=new DataOutputStream(conn.getOutputStream());
FileInputStream fs=new FileInputStream(file);
byte[] bytes=new byte[1024*1024];
int len=-1;
out.write(split.toString().getBytes());
while((len=fs.read(bytes)) != -1){
out.write(bytes, 0, len);
}
out.write(lineEnd.getBytes());
split = new StringBuilder();
split.append(twoHyphens + boundary + "--" +lineEnd);
//split.append("Content-Disposition: form-data; name=\" wxupload\"" + lineEnd);
//split.append(lineEnd);
//split.append("submit" + lineEnd);
//split.append(twoHyphens + boundary + lineEnd);
split.append(lineEnd);
out.write(split.toString().getBytes());
fs.close();
out.flush();
out.close();
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line,result="";
while ((line = in.readLine())!= null)
{
result += "\n" + line;
}
return result;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
LogUtil.logWarn(getClass(), "httpUpload",e.getMessage());
}
return null;
}
}
以上的类的GET访问与POST访问可查看具体的实现,编写类时有参考网上其他的编写方法,但是忘了具体的地方,在可说声抱歉,此风格是借鉴的,望原作者见谅!
其他的实现请看下回分解。谢谢!
如有错误的地方,请指正!
HttpVisit类中还有一个文件上传的方法,但是好像不对,传到服务器上说是内容丢失,我也无解,这是按照HTML表单提交时查看其提交格式写出来的,麻烦各位帮忙调试一下,我是在做往微信服务器上传多媒体文件时写的,后来实在是弄不了了,就换了个其他的第三方JAR,HttpClient 也很好用。