与Weather1不同,Weather2演示了如何使用Java调用Web Service,并且通过解析 "GenericType" 返回对象生成最终的Java对象。用户界面组件是绑定到Java Bean上,而不是直接绑定到Web Service上。
这样做最大的好处是:可以尽可能地控制服务的访问,比如缓存结果数据,这样,即使服务不在线,仍然可以快速提供响应。
这种实现方式的目的让应用与网络尽可能地“绝缘”。
知识点:
1. 点击天气查询按钮,调用的是WeatherBean.java中的方法callForecast,后者会调用CityInformation.java中的方法retrieveForecast
public boolean retrieveForecast(String zip) {
// Before we get any forecast, we get the WeatherInfo if it's not retrieved yet
weatherInfo.retreiveWeatherInfo();
boolean ret = false;
Trace.log(Utility.ApplicationLogger, Level.INFO, WeatherBean.class, "retrieveForecast",
">>>>>> Inside retrieveForecast");
List pnames = new ArrayList();
List params = new ArrayList();
List ptypes = new ArrayList();
pnames.add("ZIP");
ptypes.add(String.class);
params.add(zip);
// First lets clear the cityForecast
cityForecast.setSuccess((Boolean)Boolean.FALSE);
cityForecast.setResponseText((String)"");
cityForecast.setCity((String)"");
cityForecast.setState((String)"");
cityForecast.setWeatherStationCity((String)"");
cityForecast.clearForecast();
try {
Trace.log(Utility.ApplicationLogger, Level.INFO, WeatherBean.class, "retrieveForecast",
">>>>>> Before invokeDataControlMethod");
// This calls the DC method and gives us the Return
GenericType result =
(GenericType)AdfmfJavaUtilities.invokeDataControlMethod("WeatherDC", null, "GetCityForecastByZIP",
pnames, params, ptypes);
// This will give us the CityForeCast object from the result
GenericType cfgt = (GenericType)result.getAttribute(0);
// Read the attributes from the GenericType returend from the getCityForecastByZip call
cityForecast.setSuccess((Boolean)cfgt.getAttribute("Success"));
cityForecast.setResponseText((String)cfgt.getAttribute("ResponseText"));
cityForecast.setCity((String)cfgt.getAttribute("City"));
cityForecast.setState((String)cfgt.getAttribute("State"));
cityForecast.setWeatherStationCity((String)cfgt.getAttribute("WeatherStationCity"));
// This will give us the ForecastResult which is a collection of Forecast objects
GenericType frgt = (GenericType)cfgt.getAttribute("ForecastResult");
// fcgt is a collection of Forecast objects, get all those in a loop
int count = frgt.getAttributeCount();
for (int i = 0; i < count; i++) {
// Get each individual WeatherDescription object
GenericType fgt = (GenericType)frgt.getAttribute(i);
// Now make a real WeatherDescription java object out of this GenericType
Forecast f = (Forecast)GenericTypeBeanSerializationHelper.fromGenericType(Forecast.class, fgt);
f.weatherInfo = weatherInfo;
// Now get the Temperature subobject
GenericType tempgt = (GenericType)fgt.getAttribute("Temperatures");
// Now set the high and low temps
f.setDaytimeHigh((String)tempgt.getAttribute(0));
f.setMorningLow((String)tempgt.getAttribute(1));
// Now add this to our holder of all WeatherDescriptions
cityForecast.addForecast(f);
}
ret = true;
Trace.log(Utility.ApplicationLogger, Level.INFO, WeatherBean.class, "retrieveForecast",
">>>>>> After invokeDataControlMethod");
} catch (AdfInvocationException e) {
Trace.log(Utility.ApplicationLogger, Level.SEVERE, WeatherBean.class, "retrieveForecast",
">>>>>> AdfInvocationException=" + e.getMessage());
AdfException ex = new AdfException("Error Invoking Web Service. Please try later", AdfException.WARNING);
throw ex;
} catch (Exception e2) {
Trace.log(Utility.ApplicationLogger, Level.SEVERE, WeatherBean.class, "retrieveForecast",
">>>>>> Exception=" + e2.getMessage());
AdfException ex = new AdfException("Error Invoking Web Service. Please try later", AdfException.WARNING);
throw ex;
}
return ret;
}
说明:
(1)使用AdfmfJavaUtilities.invokeDataControlMethod调用Data Control中的方法,也就是真正的Web Service。
(2)返回值的类型是GenericType,后面是解析GenericType的逻辑,其中包括城市信息和城市未来5天的天气预报信息。
(3)异常的处理使用的是AdfException,如果调用出错,在界面会显示该错误。
2. 查询结果页面也不是绑定到Web Servcie Data Control上的,而是CityInformation.java生成的Data Control。
3. 这个例子中,模型层的基本设计是这样的
(1)CityInformation->CityForecast->Forecast,生成CityInformation Data Control,用于城市天气查询结果页面绑定。
(2)WeatherInformation->WeatherDescription,生成WeatherInformation Data Control,用于天气类型页面绑定。
(3)Web Service Data Control依然通过WSDL生成,不过不直接绑定到页面按钮上,而是在代码中,通过AdfmfJavaUtilities.invokeDataControlMethod调用。
(4)更进一步设想,如果需要缓存数据,可以修改相应的CityInformation.java和WeatherInformation.java,这正是这种模型层设计的好处。
参考文献:
1. https://blogs.oracle.com/mobile/entry/web_services_example_part_2
没有评论:
发表评论