HttpServletRequest gets lost once every three requests - java

Despite of being hard to choose a title for my question, here is the problem.
For my login page, I have managed to use spring web flow. One of the main stages in login process is that, if the user is trying to login and has provided wrong username and password more than three times, there should be a captcha verification as well. Hence, here is the captcha class:
public final class CaptchaErrorCountAction extends AbstractAction {
private String COUNT = "count";
private String SHOWCAPTCHA = "showCaptcha";
protected Event doExecute(final RequestContext context) {
Integer count;
HttpServletRequest request = WebUtils.getHttpServletRequest(context);
try {
count = (Integer) request.getSession().getAttribute("count");
if (count == null) {
count = 0;
}
} catch (Exception e) {
count = 0;
}
count++;
request.getSession().setAttribute(COUNT, count);
request.getSession().setAttribute(SHOWCAPTCHA, true);
return success();
}
}
In google chrome, everything is fine and the count variable shows the number of failed login attempts with a simple break point. But in firefox, 3rd, 6th, 9th, ... failed login attempts never gets to count++ and seemly gets lots. what would seem to be the problem?

Related

Concurrency for recursive webcrawler-algorithm in Java

I wrote a program in Java to find all pages of a website, starting with the URL of the startpage (using Jsoup as webcrawler). It is ok for small websites but too slow for sites with 200 or more pages:
public class SiteInspector {
private ObservableSet<String> allUrlsOfDomain; // all URLS found for site
private Set<String> toVisit; // pages that were found but not visited yet
private Set<String> visited; // URLS that were visited
private List<String> invalid; // broken URLs
public SiteInspector() {...}
public void getAllWebPagesOfSite(String entry) //entry must be startpage of a site
{
toVisit.add(entry);
allUrlsOfDomain.add(entry);
while(!toVisit.isEmpty())
{
String next = popElement(toVisit);
getAllLinksOfPage(next); //expensive
toVisit.remove(next);
}
}
public void getAllLinksOfPage(String pageURL) {
try {
if (urlIsValid(pageURL)) {
visited.add(pageURL);
Document document = Jsoup.connect(pageURL).get(); //connect to pageURL (expensive network operation)
Elements links = document.select("a"); //get all links from page
for(Element link : links)
{
String nextUrl = link.attr("abs:href"); // "http://..."
if(nextUrl.contains(new URL(pageURL).getHost())) //ignore URLs to external hosts
{
if(!isForbiddenForCrawlers(nextUrl)) // URLS forbidden by robots.txt
{
if(!visited.contains(nextUrl))
{
toVisit.add(nextUrl);
}
}
allUrlsOfDomain.add(nextUrl);
}
}
}
else
{
invalid.add(pageURL); //URL-validation fails
}
}
catch (IOException e) {
e.printStackTrace();
}
}
private boolean isForbiddenForCrawlers(String url){...}
private boolean urlIsValid(String url) {...}
public String popElement(Set<String> set) {...}
I know I have to run the expensive network-operation in extra threads.
Document document = Jsoup.connect(pageURL).get(); //connect to pageURL
My problem is that I have no idea how to properly outsource this operation while keeping the sets consistent (how to synchronize?). If possible I want to use a ThreadPoolExecutor to control the amount of threads that is getting started during the process. Do you guys have an idea how to solve this? Thanks in advance.
To use threads and also keep the sets consistent, you just need to create a thread that receives the variable you want to add to the Set but created empty, so the thread fills it when done and then adds it to the Set.
A simple example of that could be:
Main.class
for (String link : links) {
String validUrl = null;
taskThread = new Thread( new WebDownloadThreadHanlder(link, validUrl, barrier));
taskThread.start();
if (validUrl != null) {
allUrlsOfDomain.add(validUrl);
}
}
barrier.acquireUninterruptibly(links.size());
WebDownloadThreadHandler.class
public class WebDownloadThreadHandler implements Runnable {
private String link;
private String validUrl;
private Semaphore barrier;
public ScopusThreadHandler(String link, String validUrl, Semaphore barrier) {
this.link = link;
this.validUrl = null;
this.barrier = barrier;
}
public void run () {
try {
Document document = Jsoup.connect(this.link).userAgent("Mozilla/5.0");
Elements elements = document.select(YOUR CSS QUERY);
/*
YOUR JSOUP CODE GOES HERE, AND STORE THE VALID URL IN: this.validUrl = THE VALUE YOU GET;
*/
} catch (IOException) {
e.printStackTrace();
}
this.barrier.release();
}
}
What you are doing here is creating a thread for every web you want to get all the links from, and storing them into variables, if you want to retrieve more than one lvalid link from every page, you can do it using a Set and adding it a to a global set (appending it). The thing is that to keep your code consistent you need to store the retrieved values in the variable you pass the thread as argument using THIS keyword.
Hope it helps! If you need anything else feel free to ask me!

Microsoft Live Connect for Bing Ads OAuth 2.0 without browser

My overall goal is to be able to automatically download a daily report using the bing ads API. To do this, I need to authenticate with OAuth (the old PasswordAuthentication method doesn't work because I have a new microsoft account). I have been through the "Authorization Code Grant Flow" manually and authorised myself successfully. The problem is:
the token is only valid for 1 hour
when the token expires, the process requires the user to manually login using a web browser again and re-allow the app access
Here's an example desktop app using OAuth
Does somebody know either
a more fitting way of authenticating?
or a way of bypassing the user interaction?
SOLUTION:
As mentioned by #eric urban it is only necessary to authorize manually, once. after that, the refresh token will do. (Not really obvious just looking at the example desktop app!)
I wrote a class to deal with all the OAuth stuff and persist the refresh token to a file
public class OAuthRefreshToken {
private static String refreshTokenFileName = "./bingAdsRefreshToken.txt";
private static String ClientId = "XXXXX";
private final OAuthDesktopMobileAuthCodeGrant oAuthDesktopMobileAuthCodeGrant = new OAuthDesktopMobileAuthCodeGrant(ClientId);
private String refreshToken;
public OAuthRefreshToken() {
oAuthDesktopMobileAuthCodeGrant.setNewTokensListener(new NewOAuthTokensReceivedListener() {
#Override
public void onNewOAuthTokensReceived(OAuthTokens newTokens) {
String refreshTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new java.util.Date());
refreshToken = newTokens.getRefreshToken();
System.out.printf("Token refresh time: %s\n", refreshTime);
writeRefreshTokenToFile();
}
});
getRefreshTokenFromFile();
refreshAccessToken();
}
public OAuthRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
writeRefreshTokenToFile();
}
public OAuthDesktopMobileAuthCodeGrant getoAuthDesktopMobileAuthCodeGrant() {
return oAuthDesktopMobileAuthCodeGrant;
}
private void refreshAccessToken(){
oAuthDesktopMobileAuthCodeGrant.requestAccessAndRefreshTokens(refreshToken);
}
private void getRefreshTokenFromFile(){
try {
refreshToken = readFile(refreshTokenFileName, Charset.defaultCharset());
} catch (IOException e) {
e.printStackTrace();
}
}
private static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
private void writeRefreshTokenToFile(){
File refreshTokenFile = new File(refreshTokenFileName);
try {
FileWriter f2 = new FileWriter(refreshTokenFile);
f2.write(refreshToken);
f2.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
System.out.printf("New refresh token: %s\n", refreshToken);
System.out.printf("Stored Safely in: %s\n", refreshTokenFileName);
}
}
Use it in your app like:
final OAuthRefreshToken oAuthRefreshToken = new OAuthRefreshToken();
final OAuthDesktopMobileAuthCodeGrant oAuthDesktopMobileAuthCodeGrant = oAuthRefreshToken.getoAuthDesktopMobileAuthCodeGrant();
You are correct that user consent is required up front (once). Thereafter you can use the refresh token to request additional access tokens without user interaction. For details about Authorization Code grant flow using the Bing Ads Java SDK please see Getting Started Using Java with Bing Ads Services. Does this help?
The refresh token should not expire that quickly, they are usually permanent or last a very long time. These can however be revoked, or invalidated if you request too many of them. i believe when you have requested more than 25 different refresh tokens, they older ones start to become invalid.

Android Wait until Text to Speech OnInit is called

I had an issue where Text to Speech would not speak anything. I realised this was due to the fact that I was attempting to call 'Speak()' before TTS had initialised.
I need to wait until TTS has initialised, so that I can call 'Speak()' successfully. I thought doing something along the lines of this would work:
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
mTTSInitialised = true;
} else {
Log.e("TTS", "Initialisation Failed!");
}
}
...
while(!mTTSInitialised){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
But this fails to initialise at all. Is there a way to do this effectively?
The initialisation of the Text to Speech engine is asynchronous, which is why you realised you have to 'wait' for it to complete, before requesting that it processes an utterance.
Even when it eventually initialises successfully, it can be subsequently killed by the system, or it can of course fail to initialise, so you always need to be ready to handle a request to speak, where the engine isn't prepared.
Add the following helper class
public class PendingTTS {
private String pendingUtterance;
private int pendingQueueType;
public String getPendingUtterance() {
return this.pendingUtterance;
}
public void setPendingUtterance(#NonNull final String pendingUtterance) {
this.pendingUtterance = pendingUtterance;
}
public int getPendingQueueType() {
return this.pendingQueueType;
}
public void setPendingQueueType(final int pendingQueueType) {
this.pendingQueueType = pendingQueueType;
}
}
Assuming you're using an Activity, you need to declare the following variables:
private volatile PendingTTS pendingTTS;
private static final int MAX_INIT_ATTEMPTS = 4;
private volatile int initCount;
and initialise the Text to Speech object in onCreate()
tts = new TextToSpeech(YOURActivity.this, YOURonInitListener);
In your onInitListener you would check if there is any pending speech:
#Override
public void onInit(final int status) {
switch (status) {
case TextToSpeech.SUCCESS:
initCount = 0;
// Set up tts stuff
tts.setOnUtteranceProgressListener(YOURprogressListener);
if (pendingTTS != null) {
// We have pending speech, process it and check the result
int speechResult = tts.speak(pendingTTS.getPendingUtterance(),pendingTTS.getPendingQueueType(),
// remaining tts variables here)
switch (speechResult){
case TextToSpeech.SUCCESS:
// Result was successful
pendingTTS = null;
break;
case TextToSpeech.ERROR:
// Speech failed
// Check if it has repeatedly failed up to the max attempts
if(initCount < MAX_INIT_ATTEMPTS){
initCount ++;
tts = new TextToSpeech(YOURActivity.this, YOURonInitListener);
} else {
// Totally broken - let the user know it's not working
}
break;
}
} else {
// there was nothing to process
}
break;
case TextToSpeech.ERROR:
// Check if it has repeatedly failed up to the max attempts
if(initCount < MAX_INIT_ATTEMPTS){
initCount ++;
tts = new TextToSpeech(YOURActivity.this, YOURonInitListener);
} else {
// Totally broken - let the user know it's not working
}
break;
}
I've glued the above together from my code - where the speech and initialisation methods are all separated, but I tried to give you an overview above of everything you need to handle.
Elsewhere in your code, when you make a tts.speak(//stuff here) request, you need to check the result as demonstrated above, to make sure it was successful. Again, in my code, this is separated into one single method. If it does fail, you need to set the PendingTTS parameters prior to attempting to initialise again:
pendingTTS = new PendingTTS();
pendingTTS.setPendingQueueType(// your queue type);
pendingTTS.setPendingUtterance(// your utterance);
It is is successful, make sure pendingTTS is set to null.
The overall design is that if the initialisation failed, it will attempt to initialise again, up to the maximum allowed attempts. If the speech fails, it will attempt to initialise the engine again, firstly setting the PendingTTS parameters.
Hope you managed to follow that.
Hmm..
Not a very good idea.
You can try to add the text to the TTS queue and let it do it's work. This snippet can be inside button click, etc as:
tts.speak(toSpeak, TextToSpeech.QUEUE_ADD, null);
Small tutorial that would help.

How to enable / disable action in Netbeans Platform

I have spent almost three days trying to do a simple enable / disable of Actions in the netbeans plaform, something that I though was going to be simple, and should be a common feature is more complex than I thought.
At the begging I tried to see if there was an setEnable() method on the default actions generated and to my surprise there is not. Then I started looking into that and I found that most common method to do it was setting a conditionally enabled action (which depends on a Cookie class), So I figured out how to add a fake class to the Lookup so it gets enabled and disabled, I did it the following way. To test it out I added the following code to another action which should enable or disable the second one.
private final PlottingStarted plottingStarted = new PlottingStarted();
#Override
public void actionPerformed(ActionEvent e) {
// TODO implement action body
if (Lookup.getDefault().lookup(PlottingStarted.class) == null) {
ic.add(plottingStarted);
}else{
ic.remove(plottingStarted);
}
So PlottingStarted is a fake object I created which only purpose is being in the lookup to disable or enable the action.
For some reason it did not do anything at all an the Action was always disabled. I tried many things and finally I gave up.
Then I tried a different approach and was using AbstractActions which do have the setEnabled() ability.
To retrieve the action I based myself on one the Geertjan blogs and I created the following method
public Action findAction(String actionName) {
FileObject myActionsFolder = FileUtil.getConfigFile("Actions/RealTimeViewer");
if (myActionsFolder != null){
FileObject[] myActionsFolderKids = myActionsFolder.getChildren();
for (FileObject fileObject : myActionsFolderKids) {
//Probably want to make this more robust,
//but the point is that here we find a particular Action:
if (fileObject.getName().contains(actionName)) {
try {
DataObject dob = DataObject.find(fileObject);
InstanceCookie ic = dob.getLookup().lookup(InstanceCookie.class);
if (ic != null) {
Object instance = ic.instanceCreate();
if (instance instanceof Action) {
Action a = (Action) instance;
return a;
}
}
} catch (Exception e) {
ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
return null;
}
}
}
}
return null;
}
This method worked perfectly and I was able to retrieve the action and call its setEnabled() method. Unfortunately no matter why I did the Action was always enabled.
Reading some literature I found that I should add the following to the registration of the action "lazy = false" and finally I was able to enable and disable the Action... But off course the default registration is lost and I have no Icons and Names.
Now I decided to post again because I cannot believe that it need to be that complex, there must be a way to do it easier. The only thing I need is to have a PLAY / STOP functionality, when PLAY is enabled STOP is disabled and vice-versa.
I have not done this myself but it seems to be covered in Chapter 5.1.2.1 "Complex Enablement" of the book "Netbeans Platform for Beginners". https://leanpub.com/nbp4beginners
The book is not free but the corresponding code sample is available on
github. https://github.com/walternyland/nbp4beginners/tree/master/chapters/ch05/5.1.2.1 He extends AbstractAction overrides the resultChanged method and uses super.setEnabled().
#ActionID(id = "org.carsales.evaluator.EvaluateCarAction1", category = "Car")
#ActionRegistration(displayName = "not-used", lazy = false)
public class EvaluateCarAction extends AbstractAction
implements ContextAwareAction, LookupListener {
// ...
#Override
public void resultChanged(LookupEvent le) {
//Optionally, check if the property is set to the value you're interested in
//prior to enabling the Action.
super.setEnabled(result.allInstances().size() > 0);
}
Thanks to everybody for your responses. I finally got it to work by extending AbstractAction, it seems that even if you register "lazy = false" some of the registration is still being done by the platform and you just need some minor tweaking in the Action constructor. The final result was
#ActionID(
category = "RealTimeViewer",
id = "main.java.com.graph.actions.StopPlotting"
)
#ActionRegistration(
//iconBase = "main/java/com/graph/images/stop-plotting-24x24.png",
displayName = "#CTL_StopPlotting",
lazy = false
)
#ActionReference(path = "Toolbars/RealTimeViewer", position = 600)
#Messages("CTL_StopPlotting=Stop Plotting")
public final class StopPlotting extends AbstractAction{
private static final String ICON = "main/java/com/dacsys/cna/core/graph/images/stop-plotting-24x24.png";
public StopPlotting() {
putValue(SMALL_ICON, ImageUtilities.loadImageIcon(ICON, false));
putValue(NAME, Bundle.CTL_StopPlotting());
this.setEnabled(false);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO implement action body
Action a = new ActionsHelper().findAction("StartPlotting");
if (a != null){
if (a != null){
if (a.isEnabled()){
a.setEnabled(false);
this.setEnabled(true);
}else{
a.setEnabled(true);
this.setEnabled(false);
}
}
}
}
}

JoptionPane Validation

I have a Swing GUI where I am restricting the user registration so that the username and the password cannot be the same. I am using JoptionPane for the task with the following code:
public void actionPerformed(ActionEvent e) {
String username = tuser.getText();
String password1 = pass1.getText();
String password2 = pass2.getText();
String workclass = wclass.getText();
Connection conn = null;
try {
if(username.equalsIgnoreCase(password1)) {
JOptionPane.showMessageDialog(null,
"Username and Password Cannot be the same. Click OK to Continue",
"Error", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
...
The problem is that I had to use System.exit(0); without it, the next code was getting executed. Even after the JOptionPane poped up, the registration was succeeding. I do not need the system to exit, but I need the user to be kept on the registration page after the validation. What is the best way to do this? Is there other convenient ways of doing this rather than using the JOptionPane?
Replace
System.exit(0);
with
return;
if you do not want the rest of the method to be performed
You need to place your code within endless loop, and break it upon successful result. Something like:
while(true)
{
// get input from user
if(vlaidInput) break;
}
place that next code into else part may be it works
if(username.equalsIgnoreCase(password1))
{
JOptionPane.showMessageDialog(null, "Username and Password Cannot be the same. Click OK to Continue","Error",JOptionPane.ERROR_MESSAGE);
}
else
{
//place that next code
// username and password not equals, then it will execute the code
}
First of all, it is best if the UI and business logic (in this case, validation) are separated. Have them separate sort of suggest a better way of handling interaction on its own. Thus, it makes sense to create a separate class UserValidation with method boolean isValid(). Something like this:
public class UserValidation {
private final String name;
private final String passwd;
private final String passwdRpt;
public UserValidation(final String name, final String passwd, final String passwdRpt) {
this.name = name;
this.passwd = passwd;
this.passwdRpt = passwdRpt;
}
public boolean isValid() {
// do your validation logic and return true if successful, or false otherwise
}
}
Then the action code would look like this:
public void actionPerformed(ActionEvent e) {
if (new UserValidation(tuser.getText(), pass1.getText(), pass2.getText()).isValid()) {
// do everything needed is validation passes, which should include closing of the frame of dialog used for entering credentials.
}
// else update the UI with appropriate error message -- the dialog would not close by itself and would keep prompting user for a valid entry
}
The suggested approach gives you a way to easily unit test the validation logic and use it in different situations. Please also note that if the logic in method isValid() is heavy than it should be executed by a SwingWorker. The invocation of SwingWorker is the responsibility of the action (i.e. UI) logic.

Categories

Resources