URLTool.java
package dsh.bikegis.tool;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
/**
* 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。
* @author NanGuoCan
*
*/
public class URLTool {
public static InputStream getUrl(String city){
String host1="http://www.google.com/ig/api?hl=zh-tw&weather=";
StringBuffer host=new StringBuffer(host1);
/* String temp=null;
try {
temp = URLEncoder.encode(city,"utf-8");//把接收過來的中文進行編碼
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}*/
host.append(city);
try {
URL url=new URL(host.toString());
return url.openStream();
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
SAXParseWeatherServiceImpl.java
package dsh.bikegis.service.impl;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import dsh.bikegis.model.CurrentWeather;
import dsh.bikegis.model.ForecastWeather;
import dsh.bikegis.tool.URLTool;
public class SAXParseWeatherServiceImpl{
private List<ForecastWeather> weathers;// 本周未來幾天天氣信息
private ForecastWeather fw;//本周某天天氣信息
private CurrentWeather currentWeather;// 今天的天氣信息
/**
* 解析xml文檔
*
* @param city
* 需要解析的城市
*/
public void parserXml(String city) {
SAXParserFactory saxfac = SAXParserFactory.newInstance();
try {
SAXParser saxparser = saxfac.newSAXParser();
//InputStream is = new FileInputStream(city);
InputStream inputStream=URLTool.getUrl(city);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"big5"));
InputSource is = new InputSource(reader);
saxparser.parse(is, new MySAXHandler());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
class MySAXHandler extends DefaultHandler {
private boolean current_conditions=false;//當天天氣信息標誌
private boolean forecast_conditions=false;//本周未來幾天預測天氣信息標誌
@Override
public void startDocument() throws SAXException {
//文檔解析開始時創建一個用於保存當天天氣信息的對象
currentWeather = new CurrentWeather();
// 文檔解析開始時創創建一個用於保存未來幾天天氣信息的list
weathers = new ArrayList<ForecastWeather>();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes att) throws SAXException {
//設置預測判斷標誌
if(qName.equals("current_conditions")){
current_conditions=true;
}
//設置預測判斷標誌
if(qName.equals("forecast_conditions")){
forecast_conditions=true;
fw=new ForecastWeather();
}
//設置預測城市
if(qName.equals("city")){
currentWeather.setCity(att.getValue(0));
}
//設置預測日期
if(qName.equals("forecast_date")){
currentWeather.setForecast_date(att.getValue(0));
}
//設置當前預測時間
if(qName.equals("current_date_time")){
currentWeather.setCurrent_date_time(att.getValue(0));
}
//根據條件設置當前和未來某天天氣狀況
if(qName.equals("condition")){
if(this.current_conditions==true){
currentWeather.setCondition(att.getValue(0));
}
if(this.forecast_conditions==true){
fw.setCondition(att.getValue(0));
}
}
//根據條件設置當前和未來某天天氣氣象圖標
if(qName.equals("icon")){
if(this.current_conditions==true){
currentWeather.setIcon(att.getValue(0));
}
if(this.forecast_conditions==true){
fw.setIcon(att.getValue(0));
}
}
//設置當前天氣的華氏溫度
if(qName.equals("temp_f")){
currentWeather.setTemp_f(att.getValue(0));
}
//設置當前天氣的攝氏溫度
if(qName.equals("temp_c")){
currentWeather.setTemp_c(att.getValue(0));
}
//設置當天天氣的濕度
if(qName.equals("humidity")){
String hum=att.getValue(0).substring(3);
currentWeather.setHumidity(hum);
}
//設置當前天氣的風向和風速
if(qName.equals("wind_condition")){
String wind_direction=att.getValue(0).substring(3,5);
String wind_speed=att.getValue(0).substring(9);
currentWeather.setWind_direction(wind_direction);
currentWeather.setWind_speed(wind_speed);
}
//設置未來某天日期
if(qName.equals("day_of_week")){
fw.setDay_of_week(att.getValue(0));
}
//設置未來某天天氣的最低溫度
if(qName.equals("low")){
fw.setLow(att.getValue(0));
}
//設置未來某天天氣的最高溫度
if(qName.equals("high")){
fw.setHigh(att.getValue(0));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
//current_conditions標籤結束
if(qName.equals("current_conditions")){
this.current_conditions=false;
}
//forecast_conditions標籤結束
if(qName.equals("forecast_conditions")){
forecast_conditions=false;
weathers.add(fw);
fw=null;
}
}
}
public List<ForecastWeather> getWeathers() {
return weathers;
}
public void setWeathers(List<ForecastWeather> weathers) {
this.weathers = weathers;
}
public ForecastWeather getFw() {
return fw;
}
public void setFw(ForecastWeather fw) {
this.fw = fw;
}
public CurrentWeather getCurrentWeather() {
return currentWeather;
}
public void setCurrentWeather(CurrentWeather currentWeather) {
this.currentWeather = currentWeather;
}
}
SAXParseWeatherActionImpl.java
package dsh.bikegis.action.impl;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import org.apache.struts2.json.annotations.JSON;
import com.opensymphony.xwork2.ActionSupport;
import dsh.bikegis.action.SAXParseWeatherAction;
import dsh.bikegis.model.CurrentWeather;
import dsh.bikegis.model.ForecastWeather;
import dsh.bikegis.service.impl.SAXParseWeatherServiceImpl;
import dsh.bikegis.system.SysAction;
import dsh.bikegis.tool.JsonUtil;
/**
* 解析google weather api傳來的xml
* @author NanGuoCan
*
*/
public class SAXParseWeatherActionImpl extends SysAction implements SAXParseWeatherAction {
/**
*
*/
private static final long serialVersionUID = 1L;
private SAXParseWeatherServiceImpl saxService;
private List<ForecastWeather> lists=new ArrayList<ForecastWeather>();
private CurrentWeather currentWeather=new CurrentWeather();
private String city;//接收前臺傳來的城市名稱
private String cWeatherStr=null;
private String fWeathersStr=null;
/**
* 解析google weather api傳來的xml文件
* @return
* 成功返回success,失敗返回error
*/
@Override
public String getWeather() {
saxService.parserXml(city);
lists=saxService.getWeathers();
currentWeather=saxService.getCurrentWeather();
this.cWeatherStr=JsonUtil.beanToJson(currentWeather);
this.fWeathersStr=JsonUtil.listToJson(lists);
return ActionSupport.SUCCESS;
}
@JSON(serialize=false)
public List<ForecastWeather> getLists() {
return lists;
}
public void setLists(List<ForecastWeather> lists) {
this.lists = lists;
}
@JSON(serialize=false)
public CurrentWeather getCurrentWeather() {
return currentWeather;
}
public void setCurrentWeather(CurrentWeather currentWeather) {
this.currentWeather = currentWeather;
}
@JSON(serialize=false)
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@JSON(serialize=false)
public SAXParseWeatherServiceImpl getSaxService() {
return saxService;
}
public void setSaxService(SAXParseWeatherServiceImpl saxService) {
this.saxService = saxService;
}
@JSON(name="cWeatherStr")
public String getcWeatherStr() {
return cWeatherStr;
}
public void setcWeatherStr(String cWeatherStr) {
this.cWeatherStr = cWeatherStr;
}
@JSON(name="fWeathersStr")
public String getfWeathersStr() {
return fWeathersStr;
}
public void setfWeathersStr(String fWeathersStr) {
this.fWeathersStr = fWeathersStr;
}
}
前台ajax访问:
$.ajax({ url:"${requestScope.basePath}/main/weather/getWeatherJson.action", data:"city="+encodeURI(encodeURI(karea)), dataType:"json", beforeSend:function(){ $('#weatherstatus').html('正在查詢請稍後....'); }, success: function(data){ showweather(data); }, error:function(){ $('#weatherstatus').html('<span style="background:red;">出錯啦,請稍後再試</span>'); } });
其中注释部分代码为对传来的城市进行编码
String temp=null;
try {
temp = URLEncoder.encode(city,"utf-8");//把接收過來的城市中文進行編碼
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
即,如果传来的中文没有经过编码,而使用url在网络上进行传输的话可能会发生乱码,所以最好是经过指定格式的编码之后再让其进行传输。由于这个项目接收google传来的天气格式为
http://www.google.com/ig/api?hl=zh-tw&weather=,即为台湾地区的天气,所以xml中字体都是以繁体中文显示的,所以要想获得正确的繁体中文而不发生乱码,就得在读取xml文件的时候指定读取编码格式,即BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"big5"));
如果
http://www.google.com/ig/api?hl=zh-cn&weather=,则设置为BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"gb2312"));