I created application that runs on GAE and connects to specific page, automatically logins to this page and AFTER login I want to receive html and process it.
here is the problematic (writer.write part and connection.connect()) part of code:
this.username = URLEncoder.encode(username, "UTF-8");
this.password = URLEncoder.encode(password, "UTF-8");
this.login = "login";
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
writer.write("str_login=" + login + "&str_user=" + username
+ "&str_pass=" + password);
writer.close();
connection.connect();
I am getting IOException (connection.connect()) while establishig connection. Problem is "application/x-www-form-urlencoded" data. When I pass wrong parameters to page (for example str_pasSSs, str_usernaAAme, or no parameters at all) I am not possible to login but I do get response with html of login page. So, it seems that Google App Engine does not support this kind of communication. Is it possible to login to this page in some other way that GAE supports?
In Wireshark, I saw that username and password are sent in plaintext as line-based text data (application/x-www-form-urlencoded). I know this is not safe, but it's the way it is.
The connection is already established implicitly when you call getOutputStream(). There is no need to call connection.connect() again.
Also, instead of closing the output writer, try flush() instead.
As a best practice, you should be closing in, out and conn in a finally block:
InputStream in = null;
OutputStream out = null;
HttpUrlConnection conn = null;
try {
...
} catch (IOException ioe) {
...
} finally {
if (in!=null) {try {in.close()} catch (IOException e) {}}
if (out!=null) {try {out.close()} catch (IOException e) {}}
if (conn!=null) {try {conn.close()} catch (IOException e) {}}
}
Related
I have ADF web application developed using Jdeveloper 12.1.3 version, Glassfish server 3.1.2 version and Apache Shiro for security.
Login action and application security are working fine, but not logout action.
After logged out from application, it should be redirected to login page. But it throws
"javax.servlet.ServletException: java.lang.IllegalStateException:
org.apache.shiro.session.UnknownSessionException: There is no session
with id" error.
Logout action method code is
public String logout() throws IOException {
try {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
SecurityUtils.getSubject().logout();
} catch (Exception e) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "");
FacesContext.getCurrentInstance().addMessage(null, msg);
e.printStackTrace(); // TODO: logger.
}
return "";
}
Do I miss anything ?
It looks like you invalidating the session and then calling logout. Have you tried logging out first? Or something like:
Subject subject = SecurityUtils.getSubject();
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
subject.logout();
Otherwise, it looks like you are trying to get the current subject from an empty session.
I am using google app engine's urlfetch sevice to get book description from google play. When I fetch the url
https://play.google.com/store/books
, I can get correct web page html content and parse it in my local developement enviroment. But on production server, Google Play just give me a "Unavailable in your country" page.
This is my test code referenced from GAE document(https://developers.google.com/appengine/docs/java/urlfetch/usingjavanet)
try {
URL url = new URL("https://play.google.com/store/books");
final URLConnection connection = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// connection.setRequestProperty("Accept-Language", "en-US");
String line;
while ((line = reader.readLine()) != null) {
log.warn(line);
}
reader.close();
} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}
I also try to change request property "Accept-Language" but not work. Do you have any ideas for this ?
I am using wakefull intent service and works very fine. But currently i see that many times my intent service is in wait satate.I found that problem is with javamail as it goes in deadlock state when ever internet connection is resets.
I search option to intrupt operation java mail but can't find any solution.I have set IMAP,SMTP Time out property but it is not working.
if(msg1[0]!= null)
{
if(!Mail.store.isConnected() || f== null)
{
Log.v(tag, "StoreNot Connected");
m = new Mail(username, password);
f =m.getlable("Message_"+nick);
Log.v(tag, "Store Connected");
}
try{
Log.v(tag, "Sending Mail");
//Get DeadLock Hear
f.appendMessages(msg1);
sucess_flag=1;
Log.v(tag, "Mail Send");
}
catch(Exception e)
{
e.printStackTrace();
}catch(Throwable e)
{
e.printStackTrace();
}
}
So now i am looking for an option to restart or kill the current intent service.
Is there any option for this?
If not then is it a good idea to create theads from intentservice and kill them instead?
Try this:
Intent GPSService = new Intent(context, TrackGPS.class);
context.stopService(GPSService);
I am getting no where now. When I Google around to find a sample of "Exporting data to Google Spreadsheet from Google App Engine", I see a lot of Google Conversion API, Google Conversion API, Google Spreadsheet API and Google Docs API tutorials. But then they all deprecated from Google when I check at the Google site??? So, what is the most updated right now so I can make use of it?
=====
Okay now I use the Google Drive SDK via OAuth2 to create text file. But I have problem with this:
this is the error:
java.lang.NullPointerException at
java.net.URI$Parser.parse(URI.java:3004) at
java.net.URI.(URI.java:577) at
com.google.api.client.http.GenericUrl.(GenericUrl.java:100) at
com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:269)
at
com.google.api.services.drive.Drive$Files$Insert.executeUnparsed(Drive.java:309)
at
com.google.api.services.drive.Drive$Files$Insert.execute(Drive.java:331)
at
com.company.dashboard.service.DriveService.initDoc(DriveService.java:84)
this is the code:
private GoogleCredential buildGoogleCredential(Credential credential) {
try {
logger.warning(oauth2Service.getClientCredential().toString());
GoogleCredential googleCredential = new GoogleCredential.Builder()
.setClientSecrets(oauth2Service.getClientCredential())
.setTransport(new NetHttpTransport())
.setJsonFactory(new JacksonFactory()).build();
googleCredential.setAccessToken(credential.getAccessToken());
googleCredential.setRefreshToken(credential.getRefreshToken());
return googleCredential;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private Drive buildService(GoogleCredential credential) {
return new Drive.Builder(new NetHttpTransport(), new JacksonFactory(), credential).build();
}
public void initDoc(HttpServletRequest req)
throws Exception {
User user = UserServiceFactory.getUserService().getCurrentUser();
Credential credential = oauth2Service.getStoredCredential(
user.getUserId(),
(CredentialStore)req.getSession().getServletContext().getAttribute(OAuth2Constant.GOOG_CREDENTIAL_STORE));
if (credential != null) {
logger.warning("Using access token: " + credential.getAccessToken());
try {
GoogleCredential googleCredential = buildGoogleCredential(credential);
Drive service = buildService(googleCredential);
if (service == null) {
logger.warning("very bad!");
}
File body = new File();
body.setTitle("My document");
body.setDescription("A test document");
body.setMimeType("text/plain");
java.io.File fileContent = new java.io.File("document.txt");
FileContent mediaContent = new FileContent("text/plain", fileContent);
service.files().insert(body, mediaContent).execute();
//File file = service.files().insert(body, mediaContent).execute();
//System.out.println("File ID: " + file.getId());
} catch (HttpResponseException e) {
if (e.getStatusCode() == 401) {
logger.warning(e.getMessage());
// Credentials have been revoked.
// TODO: Redirect the user to the authorization URL.
throw new UnsupportedOperationException();
}
} catch (IOException e) {
System.out.println("An error occurred: " + e);
}
}
oauth2Service.getClientCredential() returns (xxx = client id and client secret code, not shown in here)
{"web":{"client_id":"xxx.apps.googleusercontent.com","client_secret":"xxx"}}
This is my scope:
final static List<String> SCOPES = Arrays.asList("https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/docs",
"https://www.googleapis.com/auth/drive.file");
final static String AUTH_RESOURCE_LOC = "/client_secrets.json";
final static String OATH_CALLBACK = "http://localhost:8888/oauth2callback";
This line
service.files().insert(body, mediaContent).execute();
throws NullPointerException. Any idea what had gone wrong???
P/S: Credential = com.google.api.client.auth.oauth2.Credential. I have my OAuth2 everything works good. I can retrieve user info without problem but not the Drive API. service is not null as you see I put it the log as "very bad" and it is not shown. No 401 exception is thrown means my Oauth2 is good with the scopes.
=======
DARN!!!! Finally solved the issue!!! My code was totally correct! Just I enabled the wrong API! It should be Drive API instead of Drive SDK API :/
You can generate a csv file from GAE and upload it using the Drive API with ?convert=true to have it automatically converted to a Google spreadsheet:
https://developers.google.com/drive/v2/reference/files/insert
I'm using the MailService feature of Google App Engine in my
application. It works fine in one application without any issues.
But the same code doesn't work in another app. I'm not able to figure
it out. Please help. Following is the piece of code that I use to
send mail.
public static void sendHTMLEmail(String from, String fromName, String
to, String toName, String subject, String body) {
_logger.info("entering ...");
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
_logger.info("got mail session ...");
String htmlBody = body;
try {
Message msg = new MimeMessage(session);
_logger.info("created mimemessage ...");
msg.setFrom(new InternetAddress(from,
fromName));
_logger.info("from is set ...");
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(
to, toName));
_logger.info("recipient is set ...");
msg.setSubject(subject);
_logger.info("subject is set ...");
Multipart mp = new MimeMultipart();
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(htmlBody, "text/html");
mp.addBodyPart(htmlPart);
_logger.info("body part added ...");
msg.setContent(mp);
_logger.info("content is set ...");
Transport.send(msg);
_logger.info("email sent successfully.");
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}
When I look at the log (on the server admin console), it prints the
statement "content is set ..." and after that there is nothing in the
log. The mail is not sent. At times I get the following error after
the above statement is printed (and the mail is not sent).
com.google.appengine.repackaged.com.google.common.base.internal.Finalizer
getInheritableThreadLocalsField: Couldn't access
Thread.inheritableThreadLocals. Reference finalizer threads will
inherit thread local values.
But the mail quota usage keeps increasing.
Remember, this works fine in one application, but not in other. I'm
using the same set of email addresses in both the apps (for from and
to).
I'm really stuck with this. Appreciate any help.
Thank you.
Velu
Have you tried logging the exceptions? I bet one of them is being thrown - your printStackTrace will go nowhere.