How do I make a call to the Yahoo hourly weather forecast API? - weather

I have found yahoo weather forcast most helpful.
I'm able to get an hourly weather request here from Yahoo.
How can I make an API request for the above hourly weather report using an Yahoo API call to http://weather.yahooapis.com/forecastrss?w=2502265?
This is the documentation I found.

Yahoo Weather Api does not seem to support hourly forecasts, there are just a few parameters you have control over like the location in (woeid) or (lat, long) and the temperature-unit (u or f), refer here for yahoo query language.
You can use other api's AccuWeather for hourly details.

You can do using the REST API's of the programming language you want to use.. I will give Java example. (Similar thing applies to other languages too.. )'
package tests;
import org.apache.http.*;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
/**
* A simple Java REST GET example using the Apache HTTP library.
* This executes a call against the Yahoo Weather API service, which is
* actually an RSS service (http://developer.yahoo.com/weather/).
*
* Try this Twitter API URL for another example (it returns JSON results):
* http://search.twitter.com/search.json?q=%40apple
* (see this url for more twitter info: https://dev.twitter.com/docs/using-search)
*
* Apache HttpClient: http://hc.apache.org/httpclient-3.x/
*
*/
public class ApacheHttpRestClient1 {
public static void main(String[] args) {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
// specify the host, protocol, and port
HttpHost target = new HttpHost("weather.yahooapis.com", 80, "http");
// specify the get request
HttpGet getRequest = new HttpGet("/forecastrss?p=80020&u=f");
System.out.println("executing request to " + target);
HttpResponse httpResponse = httpclient.execute(target, getRequest);
HttpEntity entity = httpResponse.getEntity();
System.out.println("----------------------------------------");
System.out.println(httpResponse.getStatusLine());
Header[] headers = httpResponse.getAllHeaders();
for (int i = 0; i < headers.length; i++) {
System.out.println(headers[i]);
}
System.out.println("----------------------------------------");
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
There are more ways to do the same... you can find many other alternate ways at http://alvinalexander.com/java/java-apache-httpclient-restful-client-examples

Related

JBoss 6 EAP - override HTTP response status code in a SOAP service that sends empty response back from 202 to 200

We have a SOAP web service that we are migrating from JBoss EAP 5.1 to 6.4.7 and one of the webservices returns absolutely nothing but 200 (in JBoss 5). When we migrated to 6 it still works and returns nothing but returns a 202 instead and that is going to break clients. We have no control over clients. I tried a SOAPHandler at the close method but it does nothing as it is not even called as my guess is that since there is no SOAP message going back there is nothing that triggers the handler.
I also tried to access the context directly in the web method and modif but it did nothing.
MessageContext ctx = wsContext.getMessageContext();
HttpServletResponse response = (HttpServletResponse) ctx.get(MessageContext.SERVLET_RESPONSE);
response.setStatus(HttpServletResponse.SC_OK);
I couldn't find anything in the manual.
Any direction is very much appreciated.
Here is how the port and its implementation look like:
Here is how the port and its implementation head look like:
#WebService(name = "ForecastServicePortType", targetNamespace = "http://www.company.com/forecastservice/wsdl")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#XmlSeeAlso({
ObjectFactory.class
})
public interface ForecastServicePortType {
/**
*
* #param parameters
* #throws RemoteException
*/
#WebMethod(action = "http://www.company.com/forecast/sendForecast")
public void sendForecast(
#WebParam(name = "SendForecast", targetNamespace = "http://www.company.com/forecastservice", partName = "parameters")
SendForecastType parameters) throws RemoteException;
}
#WebService(name = "ForecastServicePortTypeImpl", serviceName = "ForecastServicePortType", endpointInterface = "com.company.forecastservice.wsdl.ForecastServicePortType", wsdlLocation = "/WEB-INF/wsdl/ForecastServicePortType.wsdl")
#HandlerChain(file = "/META-INF/handlers.xml")
public class ForecastServicePortTypeImpl implements ForecastServicePortType {
...
}
In case anybody will find this useful. Here is the solution;
Apache CXF by default uses async requests and even if the annotation #OneWay is missing it still behaves as it if was there.
So in order to disable that an interceptor needs to be created like below:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import java.util.Arrays;
public class DisableOneWayInterceptor extends AbstractSoapInterceptor {
private static final Log LOG = LogFactory.getLog(DisableOneWayInterceptor.class);
public DisableOneWayInterceptor(){
super(Phase.PRE_LOGICAL);
addBefore(Arrays.asList(org.apache.cxf.interceptor.OneWayProcessorInterceptor.class.getName()));
}
#Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
if(LOG.isDebugEnabled())
LOG.debug("OneWay behavior disabled");
soapMessage.getExchange().setOneWay(false);
}
}
And called in WebService class (annotated with #WebService) as below:
#org.apache.cxf.interceptor.InInterceptors (interceptors = {"com.mycompany.interceptors.DisableOneWayInterceptor" })

(Android Studio) Connecting an app to Google Endpoints Module

I'm having trouble following the second step here.
I really don't understand how this sample does anything other than return a simple toast message. How does it utilize the API to display that message?
class EndpointsAsyncTask extends AsyncTask<Pair<Context, String>, Void, String> {
private static MyApi myApiService = null;
private Context context;
#Override
protected String doInBackground(Pair<Context, String>... params) {
if(myApiService == null) { // Only do this once
MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
// end options for devappserver
myApiService = builder.build();
}
context = params[0].first;
String name = params[0].second;
try {
return myApiService.sayHi(name).execute().getData();
} catch (IOException e) {
return e.getMessage();
}
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
I'm afraid my this sample is too complex for my limited knowledge. How exactly do I "talk" to the Google Endpoints Module when running an app? Specifically, What is EndpointsAsyncTask();?
Are there any resources listing all the methods available to me? Is there a simpler example of an app communicating with a Google Cloud Endpoint?
The service methods available to you are defined by the backend source in section 1.
In the example you posted, this line: myApiService.sayHi(name).execute()
is an actual invocation call to the backend that you defined by annotating #ApiMethod("sayHi") on the method in the MyEndpoint.java class of your backend module.
The reason your Android app defines an EndpointsAsyncTask is because slow operations such as calls that hit the network need to happen off of the UI thread to avoid locking the UI. The demo simply puts the returned value into a Toast but you could modify onPostExecute() to do whatever you'd like with the result.
For more info on Google Endpoints check out:
https://cloud.google.com/appengine/docs/java/endpoints/
And for info about using an Android AsyncTask look here:
http://developer.android.com/reference/android/os/AsyncTask.html

How to use REST API for sending messages to Azure Notification Hub from Java/GAE

I have successfully implemented calling GAE -> Azure Mobile Services -> Azure Notification HUB.
But I want to skip the Mobile Services step and call the notification HUB directly and I can't figure out how to send the authorization token. The returned error is:
Returned response: <Error><Code>401</Code><Detail>MissingAudience: The provided token does not
specify the 'Audience'..TrackingId:6a9a452d-c3bf-4fed-b0b0-975210f7a13c_G14,TimeStamp:11/26/2013 12:47:40 PM</Detail></Error>
Here is my code:
URL url = new URL("https://myapp-ns.servicebus.windows.net/myhubbie/messages/?api-version=2013-08");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(60000);
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
connection.setRequestProperty("Authorization","WRAP access_token=\"mytoken_taken_from_azure_portal=\"");
connection.setRequestProperty("ServiceBusNotification-Tags", tag);
byte[] notificationMessage = new byte[0];
try
{
notificationMessage = json.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
log.warning("Error encoding toast message to UTF8! Error=" + e.getMessage());
}
connection.setRequestProperty("Content-Length", String.valueOf(notificationMessage.length));
OutputStream ostream = connection.getOutputStream();
ostream.write(notificationMessage);
ostream.flush();
ostream.close();
int responseCode = connection.getResponseCode();
The authorization header has to contain a token specially crafted for each individual request. The data you are using is the key you have to use to generate such a token.
Please follow the instructions on : http://msdn.microsoft.com/en-us/library/dn495627.aspx to create a token for your requests.
Final note, if you are using Java, you can use the code in this public repo https://github.com/fsautomata/notificationhubs-rest-java. It contains a fully functional REST wrapper for Notification Hubs. It is not Microsoft official but works and implements the above specs.

NoClassDefFoundError: javax.naming.directory.InitialDirContext is a restricted class. Using CCS (GCM) in Google App Engine

Im trying to implement google's Cloud Connection Server with Google App Engine following this tutorial -
Implementing an XMPP-based App Server. I copied latest smack jars from http://www.igniterealtime.org/projects/smack/ (smack.jar and smackx.jar), put them in WEB-INF/lib and added them to the classpath (im using eclipse).
In the code sample in the first link i posted, the XMPPConnection is initiated in a 'main' method. Since this is not really suitable to GAE i created a ServletContextListener and added it to web.xml.
public class GCMContextListener implements ServletContextListener {
private static final String GCM_SENDER_ID = "*GCM_SENDER_ID*";
private static final String API_KEY = "*API_KEY*";
private SmackCcsClient ccsClient;
public GCMContextListener() {
}
#Override
public void contextInitialized(ServletContextEvent arg0) {
final String userName = GCM_SENDER_ID + "#gcm.googleapis.com";
final String password = API_KEY;
ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
try {
ccsClient.disconnect();
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
web.xml
<web-app>
<listener>
<listener-class>com.myserver.bootstrap.GCMContextListener</listener-class>
</listener>
</web-app>
Now, when i start the GAE server i get the following exception :
java.lang.NoClassDefFoundError: javax.naming.directory.InitialDirContext is a restricted class. Please see the Google App Engine developer's guide for more details.
i searched the "Google App Engine developer's guide for more details" but couldnt find anything about this. can you please help me ?
Google App Engine restricts access to certain JRE classes. In fact they published a whitelist that shows you which classes are useable. It seems to me that the Smack library might require some reference to a directory context (maybe to create the XMPP messages?) and that is why your servlet causes this exception. The javax.naming.directory is not in the whitelist.
I'm currently working on setting up a GCM Server as well. It seems to me that you need to read through the example and see what that main method is doing. What I see is a connection to the GCM server:
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
Then a downstream message being sent to a device:
// Send a sample hello downstream message to a device.
String toRegId = "RegistrationIdOfTheTargetDevice";
String messageId = ccsClient.getRandomMessageId();
Map<String, String> payload = new HashMap<String, String>();
payload.put("Hello", "World");
payload.put("CCS", "Dummy Message");
payload.put("EmbeddedMessageId", messageId);
String collapseKey = "sample";
Long timeToLive = 10000L;
Boolean delayWhileIdle = true;
ccsClient.send(createJsonMessage(toRegId, messageId, payload, collapseKey,
timeToLive, delayWhileIdle));
}
These operations would be completed at some point during your application's lifecycle, so your servlet should support them by providing the methods the example is implementing, such as the connect method that appears in the first piece of code that I pasted here. It's implementation is in the example at line 235 if I'm not mistaken.
As the documentation says, the 3rd party application server, which is what you're trying to implement using GAE, should be:
Able to communicate with your client.
Able to fire off properly formatted requests to the GCM server.
Able to handle requests and resend them as needed, using exponential back-off.
Able to store the API key and client registration IDs. The API key is included in the header of POST requests that send messages.
Able to store the API key and client registration IDs.
Able to generate message IDs to uniquely identify each message it sends.

Testing server deployed on Google App Engine

I want to test a server I have deployed on GAE to see if a connection can be made via a HTTP POST request. The end client will run on Android but for now I would like to run a simple test on my laptop.
I send different "action" params as part of the request to the server and based on the action it will look for and handle other params to complete the request. Below is an example of how a command is handled. One param is the action and the other a username. It will in the end return a JSON object with the groups this user is a member of but for now I want to just get the test string "Just a test" back to see everything is working.
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
.
.
.
.
/*
* GET GROUPS
*
* #param action == getGroups
* #param user == the username of the user making the request
*/
else if(request.getParameter("action").equals("getGroups")) {
/* Query for the User by username */
User user = queryUser(request.getParameter("user"), pm);
/* Generate the list of groups this user belongs to */
ArrayList<Group> groups = null;
if(user != null) {
groups = new ArrayList<Group>(user.groups().size());
for(Group group : user.groups())
groups.add(group);
}
/* Send response back to the client */
response.setContentType("text/plain");
response.getWriter().write("Just a test");
}
A side question, do I send HTTP POST requests to http://myapp.appspot.com/myapplink
or just to http://myapp.appspot.com/?
I have low experience writing client-server code so I was looking for help and examples of a simple POST request using supplied params and then reading the response back (with in my example the test string) and display it to the terminal.
Here is a sample of a test I was running:
public static void main(String[] args) throws IOException {
String urlParameters = "action=getGroups&username=homer.simpson";
String request = "http://myapp.appspot.com/myapplink";
URL url = new URL(request);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("charset", "utf-8");
connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length));
connection.setUseCaches (false);
DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
if ( connection.getResponseCode() == HttpURLConnection.HTTP_OK ){
System.out.println("Posted ok!");
System.out.println("Res" + connection.getResponseMessage()); //OK read
System.out.println("Size: "+connection.getContentLength()); // is 0
System.out.println("RespCode: "+connection.getResponseCode()); // is 200
System.out.println("RespMsg: "+connection.getResponseMessage()); // is 'OK'
}
else {
System.out.println("Bad post...");
}
}
When executing however, I get that it's a "bad post"
Usually you will want to send it to a particular link, so you have a way of separating the different servlet classes. Assuming that the doPost() method is inside MyAppLinkServlet class in the package myapp, you will need a web.xml file like the one below to describe how you will respond to the link. BTW, the code is only slightly modified from the GAE/J example at http://code.google.com/appengine/docs/java/gettingstarted/creating.html
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>myapplink</servlet-name>
<servlet-class>myapp.MyAppLinkServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myapplink</servlet-name>
<url-pattern>/myapplink</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
On the server, try adding the line
response.setStatus(200);
(which effectively sets the status as "OK").
On the client side, try something simple to start, such as:
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class TestRequest {
public static void main(String[] args) throws IOException {
String urlParameters = "action=getGroups&username=homer.simpson";
String request = "http://myapp.appspot.com/myapplink";
URL postUrl = new URL (request+"?"+urlParameters);
System.out.println(readFromUrl(postUrl));
}
private static String readFromUrl (URL url) throws IOException {
FetchOptions opt = FetchOptions.Builder.doNotValidateCertificate(); //depending on how did you install GAE, you might not need this anymore
HTTPRequest request = new HTTPRequest (url, HTTPMethod.POST, opt);
URLFetchService service = URLFetchServiceFactory.getURLFetchService();
HTTPResponse response = service.fetch(request);
if (response.getResponseCode() == HttpURLConnection.HTTP_OK) {
byte[] content = response.getContent();
return new String(content);
} else {
return null;
}
}
}
Good luck!

Resources