I have this code below that encodes a URL before it is send over the wire (email):
private static String urlFor(HttpServletRequest request, String code, String email, boolean forgot) {
try {
URI url = forgot
? new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(), createHtmlLink(),
"code="+code+"&email="+email+"&forgot=true", null)
: new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(), createHtmlLink(),
"code="+code+"&email="+email, null);
String s = url.toString();
return s;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
/**
* Create the part of the URL taking into consideration if
* its running on dev mode or production
*
* #return
*/
public static String createHtmlLink(){
if (GAEUtils.isGaeProd()){
return "/index.html#ConfirmRegisterPage;";
} else {
return "/index.html?gwt.codesvr=127.0.0.1:9997#ConfirmRegisterPage;";
}
}
The problem with this is that the generated email looks like this:
http://127.0.0.1:8888/index.html%3Fgwt.codesvr=127.0.0.1:9997%23ConfirmRegisterPage;?code=fdc12e195d&email=demo#email.com
The ? mark and # symbol is replaced with %3F and %23 where when the link is opened from the browser it will not open as it is incorrect.
What is the correct way to do this?
You need to combine the query-parts of the url and add the fragment as the correct parameter.
Something like this should work:
private static String urlFor(HttpServletRequest request, String code, String email, boolean forgot) {
try {
URI htmlLink = new URI(createHtmlLink());
String query = htmlLink.getQuery();
String fragment = htmlLink.getFragment();
fragment += "code="+code+"&email="+email;
if(forgot){
fragment += "&forgot=true";
}
URI url = new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(), htmlLink.getPath(),
query, fragment);
String s = url.toString();
return s;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
You can use the Java API method URLEncoder#encode(). Encode the query parameters using the method.
A better API for doing this is the UriBuilder.
Related
So I'm working on an assignment where I have to create a TabLayout representing different categories of news, where the news is retrieved using the Bing search API and the JSON is parsed and used to populate the ListView in the three Fragments that make up the TabLayout. I'm also using a ViewPager.
My issue is that for some reason, the content of all three Fragments is the same... same article results. Why is this? I'm using Loader IDs, and the loader is initialized in the onActivityCreated() method. Is there a way I can load the articles relevant to the current Fragment when the user swipes over to that tab?
Here are the relevant methods of my Fragments. They're almost identical in each Fragment, with the exception of the LOADER_ID and CATEGORY_NAME values.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Get a reference to the ConnectivityManager to check state of network connectivity
ConnectivityManager connMgr = (ConnectivityManager)
getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
// Get details on the currently active default data network
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
// If there is a network connection, fetch data
if (networkInfo != null && networkInfo.isConnected()) {
// Get a reference to the LoaderManager, in order to interact with loaders.
LoaderManager loaderManager = getLoaderManager();
// Initialize the loader. Pass in the int ID constant defined above and pass in null for
// the bundle. Pass in this activity for the LoaderCallbacks parameter (which is valid
// because this activity implements the LoaderCallbacks interface).
loaderManager.initLoader(WorldFragment.LOADER_ID, null, this);
} else {
// Otherwise, display error
// First, hide loading indicator so error message will be visible
View loadingIndicator = getActivity().findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
// Update empty state with no connection error message
mEmptyStateTextView.setText(R.string.no_internet_connection);
}
}
#Override
public Loader<List<Article>> onCreateLoader(int id, Bundle args) {
return new ArticleLoader(this.getContext(), WorldFragment.CATEGORY_NAME);
}
#Override
public void onLoadFinished(Loader<List<Article>> loader, List<Article> articles) {
// Hide loading indicator because the data has been loaded
View loadingIndicator = getActivity().findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
// Set empty state text to display "No articles found."
mEmptyStateTextView.setText(R.string.no_articles);
// Clear the adapter of previous earthquake data
adapter.clear();
// If there is a valid list of {#link Earthquake}s, then add them to the adapter's
// data set. This will trigger the ListView to update.
if (articles != null && !articles.isEmpty()) {
adapter.addAll(articles);
}
}
#Override
public void onLoaderReset(Loader<List<Article>> loader) {
adapter.clear();
}
And here is the source for my ArticleLoader class. The "fetchArticleData" call is what retrieves the Article objects by parsing the JSON into Article objects.
public class ArticleLoader extends AsyncTaskLoader<List<Article>> {
private static final String LOG_TAG = ArticleLoader.class.getName();
private String category;
public ArticleLoader(Context context, String category) {
super(context);
this.category = category;
}
#Override
protected void onStartLoading() {
forceLoad();
}
#Override
public List<Article> loadInBackground() {
if (category == null) {
return null;
}
// Perform the network request, parse the response, and extract a list of earthquakes.
List<Article> articles = QueryUtils.fetchArticleData(category);
return articles;
}
}
As per request, here is the QueryUtils class.
public class QueryUtils {
private static final String LOG_TAG = QueryUtils.class.getSimpleName();
private static final String REQUEST_BASE_URL = "https://api.cognitive.microsoft.com/bing/v5.0/news/";
private static final String API_KEY = "redacted";
/**
* Create a private constructor because no one should ever create a {#link QueryUtils} object.
* This class is only meant to hold static variables and methods, which can be accessed
* directly from the class name QueryUtils (and an object instance of QueryUtils is not needed).
*/
private QueryUtils() {
}
/**
* Query the USGS dataset and return a list of {#link Article} objects.
*/
public static List<Article> fetchArticleData(String category) {
// Create URL object
HttpURLConnection conn = createUrlConnection(category);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(conn);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request.", e);
}
// Extract relevant fields from the JSON response and create a list of {#link Article}s
List<Article> articles = extractFeatureFromJson(jsonResponse);
// Return the list of {#link Article}s
return articles;
}
/**
* Returns new URL object from the given string URL.
*/
private static HttpURLConnection createUrlConnection(String category) {
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(QueryUtils.REQUEST_BASE_URL);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Category", category);
conn.setRequestProperty("Ocp-Apim-Subscription-Key", QueryUtils.API_KEY);
conn.setDoInput(true);
} catch (Exception e) {
Log.e(LOG_TAG, "Problem building the URL connection ", e);
}
return conn;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private static String makeHttpRequest(HttpURLConnection conn) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (conn == null) {
return jsonResponse;
}
InputStream inputStream = null;
try {
conn.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (conn.getResponseCode() == 200) {
inputStream = conn.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + conn.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the article JSON results.", e);
} finally {
if (conn != null) {
conn.disconnect();
}
if (inputStream != null) {
// Closing the input stream could throw an IOException, which is why
// the makeHttpRequest(URL url) method signature specifies than an IOException
// could be thrown.
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return a list of {#link Article} objects that has been built up from
* parsing the given JSON response.
*/
private static List<Article> extractFeatureFromJson(String articleJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(articleJSON)) {
return null;
}
// Create an empty ArrayList that we can start adding articles to
List<Article> articles = new ArrayList<>();
// Try to parse the JSON response string. If there's a problem with the way the JSON
// is formatted, a JSONException exception object will be thrown.
// Catch the exception so the app doesn't crash, and print the error message to the logs.
try {
// Create a JSONObject from the JSON response string
JSONObject baseJsonResponse = new JSONObject(articleJSON);
// Extract the JSONArray associated with the key called "features",
// which represents a list of features (or articles).
JSONArray articleArray = baseJsonResponse.getJSONArray("value");
// For each article in the articleArray, create an {#link Article} object
for (int i = 0; i < articleArray.length(); i++) {
// Get a single article at position i within the list of articles
JSONObject currentArticle = articleArray.getJSONObject(i);
// Extract the value for the key called "name"
String articleName = currentArticle.getString("name");
// Extract the value for the key called "url"
String articleSource = currentArticle.getString("url");
// Extract the value for the key called "image"
JSONObject imageObject = currentArticle.getJSONObject("image");
String imageSource = imageObject.getJSONObject("thumbnail").getString("contentUrl");
// Create a new {#link Article} object with the name, url, and image
// from the JSON response.
Article article = new Article(articleName, articleSource, imageSource);
// Add the new {#link Article} to the list of articles.
articles.add(article);
}
} catch (JSONException e) {
// If an error is thrown when executing any of the above statements in the "try" block,
// catch the exception here, so the app doesn't crash. Print a log message
// with the message from the exception.
Log.e("QueryUtils", "Problem parsing the article JSON results", e);
}
// Return the list of articles
return articles;
}
}
Does anyone know what I'm doing wrong?
I'm having a bit of a challenge with the JGit client. I'm embedding it in a Java App & I'd like to fetch all the repositories under an account on Github and display them. Also to add on, can I create a repository direct on Github using JGit. Like Create a Remote Repository?
I've gone through this link but it seems generic to me. Thanks in advance
The List user repositories API is something you can call from any language (including Java) and is not related to JGit.
GET /users/:username/repos
An example of Java library making those calls would be "GitHub API for Java ", and its java.org.kohsuke.github.GHPerson.java#listRepositories() method
new PagedIterator<GHRepository>(
root.retrieve().asIterator("/users/" + login + "/repos?per_page=" + pageSize,
GHRepository[].class, pageSize))
Once you get the url for those user repos, you can create JGit repos out of them.
I also doing that same Requirement To get List of repositories of a particular user
Try this one you will get All repositories of that user
//Here name means username of GitHub account
public Collection<AuthMsg> getRepos(String name) {
String url = "https://api.github.com/users/"+name+"/repos";
String data = getJSON(url);
System.out.println(data);
Type collectionType = new TypeToken<Collection<AuthMsg>>(){}.getType();
Collection<AuthMsg> enums = new Gson().fromJson(data, collectionType);
return enums;
}
//getJson method
public String getJSON(String url) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-length", "0");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
return sb.toString();
}
} catch (MalformedURLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}
//AuthMsg Class
public class AuthMsg {
//"name" which is in json what we get from url
#SerializedName("name")
private String repository;
/**
* #return the repository
*/
public String getRepository() {
return repository;
}
/**
* #param repository the repository to set
*/
public void setRepository(String repository) {
this.repository = repository;
}
}
I have a Java-method that gets a feed-document (via http) and then parses the feed (which is not of-type JSON or XML).
This is the method:
public ArrayList<ArrayList<String>> getFeed(String type)
{
String feed = "";
String address = "";
Document file;
/**
* FEED URLs-------\/
*/
switch (type) {
case "news":
address = "https://[domain]/svc/feeds/news/6001?subtree=false&imagesize=medium-square";
break;
case "events":
address = "http://[domain]/svc/feeds/events/6001?subtree=true&imagesize=medium-square&from=%5bfromDate%5d&to=%5btoDate";
}
try {
HttpURLConnection connection = (HttpURLConnection) (new URL(address)).openConnection();
//TODO: #Test
//----------------------------\/--THIS ONE WILL CAUSE ERRORS!!
file = (Document)connection.getContent();
connection.disconnect();
//OUTPUT
feed = file.getElementsByAttribute("pre").text();
stream = new StringReader(feed);
} catch (Exception e) {}
//BEGIN PARSING\\//--THEN OUTPUT//\\
try {
return parse();
} catch (FeedParseException e) {}
//de-fault
return null;
}
It's not working; saying that object:'file' caused NullPointerException.
So how do I increase my precision in debugging something which seems to me to be non-Open-Source.
P.S.: I'm not testing the "events" case so don't worry about the GET-parameters there.
here's my stack-trace:
I don't see how it helps though...
You can pass to Jsoup the URL object directly.
Instead of:
HttpURLConnection connection = (HttpURLConnection) (new URL(address)).openConnection();
//TODO: #Test
//----------------------------\/--THIS ONE WILL CAUSE ERRORS!!
file = (Document)connection.getContent();
connection.disconnect();
do
file = Jsoup //
.connect(address) //
.timeout( 10 * 1000) //
.ignoreContentType(true) //
.get();
Jsoup 1.8.3
I am working in Play framework and I am trying to import yahoo contacts.
I have cleared the yahoo authentication api's to get the access_token and guid.
With that, when I try to import the contacts using http://social.yahooapis.com/v1/user/{guid}/contacts with the auth parameters, I am getting the connection timeout exception in my page and log.
When I paste the same contact url being generated through the code in the browser, I am getting as signature_invalid
I hope I have followed all the stuffs mentioned in the yahoo api dev notes to create the oauth_signature, but still I am not getting it.
Can anyone help me on this please?
Controller code for generating signature -
public class Yahoo {
private static String token = "";
private static String currentUrl = "";
private static String verifier = "";
private static String tokenSecret = "";
private static String accessToken = "";
private static String yahooGuid = "";
public Yahoo(){
}
/**
* Requests access to the Yahoo API for request token.
* #return True if the request is successful, false if not.
*/
public static Yahoo authorize() {
Session session = Session.current();
if(session.contains("authorized") && session.get("authorized").equals("0")){
session.put("authorized", "1");
String url = getRequestTokenUrl();
WS.WSRequest request = WS.url(url);
Logger.info("Yahoo: Create request to get request token'%s'", request.url);
WS.HttpResponse response = request.get();
Logger.info("Yahoo: Token response status is %d", response.getStatus());
if (response.getStatus() == 200){
String[] pairs = response.getString().split("&");
String[] tokenSecret = pairs[1].split("=");
Yahoo.tokenSecret = tokenSecret[1];
for (String pair : pairs) {
String[] kv = pair.split("=");
if (kv.length != 2) {
break;
} else {
if (kv[0].equals("oauth_token")) {
Yahoo.token = kv[1];
}
}
}
Logger.info("level 1 - yahoo token = %s, secret = %s",Yahoo.token, Yahoo.tokenSecret);
}
}
return null;
}
/**
* Requests access to the Yahoo API for access token.
* #return True if the request is successful, false if not.
*/
public static Yahoo getAccessToken(){
String url = getAccessTokenUrl();
WS.WSRequest request = WS.url(url);
Logger.info("Yahoo: Create request to get Access token'%s'", request.url);
WS.HttpResponse response = request.get();
Logger.info("Yahoo: Token response status is %d", response.getStatus());
if (response.getStatus() == 200){
String[] pairs = response.getString().split("&");
String[] guidPair = pairs[5].split("=");
String[] tokenSecret = pairs[1].split("=");
Yahoo.tokenSecret = tokenSecret[1];
yahooGuid = guidPair[1];
for (String pair : pairs) {
String[] kv = pair.split("=");
if (kv.length != 2) {
break;
} else {
if (kv[0].equals("oauth_token")) {
Yahoo.accessToken = kv[1];
}
}
}
Logger.info("level 3 - yahoo token = %s, secret = %s, guid = %s",Yahoo.accessToken, Yahoo.tokenSecret, Yahoo.yahooGuid);
}
return null;
}
/**
* Requests Signature
* #return String
*/
public static String getBaseSignature(){
String signature = "";
String data = generateBaseString();
String key = keyString();
Logger.info("key : %s",key);
try {
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data.getBytes());
signature = new String(Base64.encode(rawHmac));
signature = java.net.URLEncoder.encode(signature, "ISO-8859-1");
Logger.info("Signature=%s", signature);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return signature;
}
/**
* Requests access to the Yahoo API for getting contacts.
*
*/
public static void getContacts(){
String url = getContactUrl();
WS.WSRequest request = WS.url(url);
Logger.info("Yahoo: Create request to get Contacts '%s'", request.url);
WS.HttpResponse response = request.get();
Logger.info("Yahoo: Token response status is %d", response.getStatus());
if (response.getStatus() == 200){
String[] pairs = response.getString().split("&");
for(int i=0;i<pairs.length;i++){
Logger.info("%s", pairs[i]);
}
}else {
//errors contains a JSON response
JsonParser parser = new JsonParser();
JsonObject message = parser.parse(response.getString()).getAsJsonObject();
Logger.error("Yahoo: Could not get token (status %d): %s", response.getStatus(), message.get("message").getAsString());
}
}
public static String generateBaseString(){
String baseString = getBaseUrl();
Logger.info("token secret : %s",tokenSecret);
Logger.info("base url : %s",baseString);
Logger.info("callback url : %s",getCallBackUrl().toString().split("oauth_token")[0].replace('?', '\0'));
String returnString = "";
try {
returnString = java.net.URLEncoder.encode("GET", "ISO-8859-1") + "&" + java.net.URLEncoder.encode("http://social.yahooapis.com/v1/user/"+yahooGuid+"/contacts", "ISO-8859-1") + "&" + java.net.URLEncoder.encode(baseString, "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Logger.info("Yahoo: Base string: %s",returnString);
return returnString;
}
public static String keyString(){
String consumerSecret = encodeString(getConsumerSecret());
String tokenSec = encodeString(tokenSecret);
String keyString = consumerSecret + encodeString("&") + tokenSec;
return keyString;
}
public static String encodeString(String msgString){
String msg = "";
try {
msg = java.net.URLEncoder.encode(msgString.toString(), "ISO-8859-1");
Logger.info("encode=%s", msg);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return msg;
}
You are getting invalid signature when you copy and paste on the browser because you are not passing the oauth headers.
I strongly suggest you using a lib to do that, I have done the exact same thing with linkedin:
http://geeks.aretotally.in/projects/play-framework-linkedin-module
You will find explanation and link to the source code.
Hope it helps.
Thank you,
Felipe
http://geeks.aretotally.in
http://playframework.info
http://mashup.fm
I want to copy a document as mentioned here:
http://code.google.com/apis/documents/docs/3.0/developers_guide_protocol.html#CopyingDocs
I am using the latest Java Gdata Library, which doesn't have a nice wrapper method to do it, and I am a newb to the java gdata lib.
I have already got an authenticated DocsService, if that is useful.
Bonus points if you wrap it un into a method which takes two Strings, one being the source name and the other being the copy name.
Ok I did it....
Just so everyone can see... this.dService is a DocsService, that already has been authenticated.
// This method returns the Resource ID to be used to make the copy
public String loadDocsSpreadsheetEntryId(String sourceName) {
String resourceId = null;
try {
Logger.info("Loading feed URL");
URL url = new URL("https://docs.google.com/feeds/default/private/full" );
DocumentQuery query = new DocumentQuery(url);
query.setTitleQuery(sourceName);
query.setTitleExact(true);
Logger.info("Loaded feed URL");
DocumentListFeed dfeed = this.dService.getFeed(query, DocumentListFeed.class);
Logger.info("got feed");
for (DocumentListEntry entry : dfeed.getEntries()) {
Logger.info(entry.getTitle().getPlainText());
if(entry.getTitle().getPlainText().equalsIgnoreCase(sourceName))
{
Logger.info("found doc");
resourceId = entry.getResourceId();
}
}
} catch(Exception e) {
logException(e, "Loading Source Spreadsheet to copy");
}
return resourceId;
}
public void createSpreadsheetFrom(String destination, String source) {
try {
URL entryUrl = new URL("http://docs.google.com/feeds/default/private/full");
Map<String, String> parameters = new HashMap<String, String>();
String resourceID = loadDocsSpreadsheetEntryId(source);
Logger.info("Resource id %s", resourceID);
DocumentListEntry newEntry = new DocumentListEntry();
newEntry.setId(resourceID);
newEntry.setTitle(new PlainTextConstruct(destination));
this.dService.insert(entryUrl, newEntry);
} catch(Exception e) {
logException(e, "Copying Spreadsheet");
}
}