Spring controller method called twice - java

I'm making a Spring MVC web app.
The problem is that on single method is called twice and I don't know why.
#RequestMapping(value="/profile/{id}", method = RequestMethod.GET)
public String displayUserProfile( #PathVariable String id) {
System.out.println("asdasddsasd");
return "account/userProfile";
}
I commented many line from this method, but is still not working. Also tried to return other view..no good luck.
In console(ulr requests are written):
/demo/account/profile/f91b3a38-6921-41e0-98b7-58dff5cb1152
asdasddsasd
/demo/account/profile/0
asdasddsasd
After the second call of tihs method, it's going to my view
Any other method work fine.
Does anyone know what's the problem here?
*I also read similar question from here..nothing helped
LE: what I also said in the comments.
What is funny is that, if I set o model to the view, on the second call of the method, my view get's the model from the first call. (on the second call, with id 0, the model is null)

I have also observed one GET request causing the controller method to execute twice. The problem occurred when requesting the service using a Chrome browser (the problem did not occur when using Postman). In my case the culprit was the JSONView Chrome extension.
I determined the cause by using the Network tab of the Chrome developer tools. It showed my GET service being requested two times. The second request was initiated by content.js, which is a JavaScript file bundled with JSONView.
After I disabled the JSONView extension, a GET request through Chrome would cause the controller method to execute only once.

I experienced this called-twice phenomenon because BrowserSync replayed HTTP requests in each open BrowserSync browser window.

I finally got some time to find a solution here.
Tried many things, but it didn't worked.
I replaced #PathVariable with #RequestParam and the URL is not accessed twice :)

Had the same problem.
Eventually I found that I have a null in a background-image url like so:
style="background-image: url(null);"
that caused to send another GET with a path variable null.

I have the same problem and find a lot of solution and finally I found the simple reason. It's in my html template css: background:url() .
This cold will run the same url again. So I just remove it out or put url in the bracket and it works.

Sounds like an issue on client side.
Open up your browser, enter <host/port/whatever_you_need_to access_the_app>/demo/account/profile/f91b3a38-6921-41e0-98b7-58dff5cb1152
and check the logs. The chances are that you'll see only one entry
Now run your client code and check network requests to the service. If you're call the controller from the browser like Chrome F12->Network tab should help.
I know it's a kind of obvious, but I think there is nothing really "unusual" in this controller, so it should be more at the level of general flow. In this case maybe it's the best to trace the HTTP traffic and see how many/when/how does it generate requests to your controller.

This might also occur due to one more reason. Because i found samething and observed following.
1st time its when your request processed and you see println statement in Console.
And if you refresh browser at method request of controller method ( example http://localhost:8080/DemoMVC/add?***) each refresh your tomcat processes request again and you get same println statement in console.

Perhaps this is too late. However, I still face these issues and forget the solution every time.
In case you are using any JS library like Angular or React then in your service call observe the response as well.
Here is a code snippet
return this.http.get<User>(`${this.resourceUrl}/activate`, { params: options, observe: 'response' })
.pipe(
filter((response: HttpResponse<User>) => response.ok),
map((response: HttpResponse<User>) => response.body),
catchError(error => {
return of(error)
})
);
The key area to focus is { params: options, observe: 'response' }

I had a controller which was listening to localhost/ and a get method which matched on a path variable something like this:
#GetMapping("/{foo}")
String get(#PathVariable(required = false) String foo)
{
return "hello world";
}
And the problem was, that after calling localhost/ I got the first call, and after that, I got the second call for the favicon.
The same would be true if you would define a context root.

Related

Wicket: double login required due to extended browser info

I have a Wicket 8.6 application. Currently, when logging in to the application, mostly (does not always happen) the user has to login twice. After the first login (after entering the credentials and clicking the submit button) a white page appears saying "If you see this, it means that both javascript and meta-refresh are not support by your browser configuration. Please click this link to continue to the original destination." This is the BrowserInfoPage. After a few seconds the user is redirected to the login page again where he/she has to enter his/her credentials again and press the login button. This time, the user logs in successfully. My question is, how do I prevent that the user hast to enter his/her credentials twice.
From my research I know that it has something to do with the collection of extended browser info. In the init method of my WicketApplication class, I had the following code:
getRequestCycleSettings().setGatherExtendedBrowserInfo(true);
However, I already commented out this code several month ago. For some reason, the described effect occurs for every new deploy now. Maybe a newly added package in the application is the reason for it. I don't know. Is there a possibility to prevent this second login maybe by creating a customized bowser info page which forwards the login? Please point me in the right direction. Thanks.
After some research, I came up with a work around. It is probably not very efficient but it works for me so far. In my custom Session class which inherits from AuthenticatedWebSession, I added the following code.
#Override
protected WebPage newBrowserInfoPage() {
final Request request = RequestCycle.get().getRequest();
if(request.getUrl().toString().contains("LoginPage")) {
if(!isSignedIn()) {
signIn(username, password);
}
PageParametersEncoder encoder = new PageParametersEncoder();
PageParameters parameters = encoder.decodePageParameters(request.getUrl());
String url = parameters != null && parameters.get("originUrl") !=null && !parameters.get("originUrl").isNull() && !parameters.get("originUrl").isEmpty()?
parameters.get("originUrl").toString("pages/home"):"pages/home";
String finalUrl=url.startsWith("pages/")?url.substring("pages/".length()):url;
throw new RedirectToUrlException(finalUrl);
}
return super.newBrowserInfoPage();
}
Some explanation to the code. As mentioned in the question, I want to prevent the user from logging in multiple times. Thus, I check if the request comes from the LoginPage and perform my work around only in that case.
During my implementation, I realized, that the method newBrowserInfoPage is called in the process when I call session.signIn(username,password); on my LoginPage. In this signIn process the authenticate method of my custom Session is called but the signedIn flag in the AuthenticatedWebSession is not changed (keeps false on successfull authentication). Is this a bug? Thus, I have to login again to set the flag to true.
Finally, I read the URL of the LoginPage where I have stored the target URL and forward the user to the target URL.
I am aware this is probably not the best approach but it is the only solution I came up with. If someone has a better idea, I am happy to hear it.

Error in backend of REST API: "INFO: The connection was broken. It was probably closed by the client. Reason: Closed"

So I am trying out a simple full stack project of my own that involves a java backend implementation of a REST API, for which I am using the org.restlet.com framework/package and jetty as the server.
Whilst I was testing my API using Postman I noticed something wierd: Every time I started the server only the first POST/PUT/DELETE HTTP Request would get an answer, while the next ones would not receive one and on the console this error message would appear:
/* Timestamp-not-important */ org.restlet.engine.adapter.ServerAdapter commit
INFO: The connection was broken. It was probably closed by the client.
Reason: Closed
The GET HTTP Requests however do not share that problem.
I said "Fair enough, probably it's postman's fault".. after all the request made it to the server and their effects were applied. However, now that I am building the front-end this problem blocks the server's response: instead of a JSON object I get an undefined (edit: actually I get 204 No Content) on the front-end and the same "INFO" on the back-end for every POST/PUT/DELETE after the first one.
I have no idea what it is or what I am doing wrong. It has to be the backend's problem, right? But what should I look for?
Nevermind, it was the stupidest thing ever. I tried to be "smart" about returning the same Representation object (with only a 'success' JSON field) on multiple occasions by making one instance on a static final field of a class. Turns out a new instance must be returned each time.

Why does weblogic's "not found" behavior change after the first attempt?

I'm using Weblogic 10.3.5. I work on a large legacy enterprise application with Struts (1.x) mapped as the default servlet.
Background
A bit of legacy convolution to start: each enterprise customer has a "subscriber ID" which their users must provide at login in addition to their username and password. Subscriber IDs are numeric and always at least four digits, usually five. If you go to mysite.com/, you are presented with a three-field login page: subscriber ID, username, and password.
Our largest enterprise customers didn't like that, so many years ago we introduced skinned login pages: go to mysite.com/12345, where 12345 is your subscriber ID. We'll prepopulate and hide the subscriber ID field, and skin the login page with the enterprise customer's logo and color scheme.
Years later, we had 100+ servlet mappings, one for each subscriber. Every new customer required a software deployment to add the servlet mapping, so our implementations team was hamstrung by the dev team's deployment schedule, which in turn was limited by our large enterprise customers' need to budget time for user acceptance testing.
To address that, we changed the URL: mysite.com/login/12345, where /login/* is mapped to a single servlet that accepts any subscriber ID. We kept the old servlet mappings around so that existing customers didn't have to change the URL, but that left two annoyances:
A few hundred lines of cruft in web.xml
As a developer or QA, it's annoying to have to know whether this is an old subscriber or a new one before you know what URL to use to log in. Try to use the old method for a new subscriber? You get a 404 page.
Here's what I did
We had a pre-existing custom 404 page, correctly defined in web.xml and behaving exactly as expected. I updated it with the following code, right at the top:
<%
if (request.getRequestURI().matches("^/[\\d]{4,}$")) {
// probably someone trying to log in with the old-style URL
response.sendRedirect(String.format("/login%s", request.getRequestURI()));
return;
}
%>
This worked like a charm, until I noticed one oddity:
Here's what's wrong
The very first time I try to visit a URL that should result in a 404 but will be redirected because it matches the regex, it doesn't redirect. With my debugger, I've determined that the reason is that request.getRequestURI() returns "/errors/404error.jsp" rather than "/12345" like I would expect, resulting in the regex not matching and our normal 404 page being served to the user.
My first thought was that something was telling the browser to redirect to the 404 page, but Chrome Dev Tools "Network" tab indicates that is not the case.
After it fails that first time, my change works every subsequent time until the application server restarts.
If I hit /login/12345 first it loads fine. Any subsequent attempt to hit /12345 will work fine, so it seems like it might have something to do with the login servlet not being fully initialized until after the first request. Weblogic is closed source, so I'm not able to dig into what's happening.
Here's my question
I know it's a pretty weird thing I'm doing; I'm open to other approaches. But the question is this: what's causing the different request URI on the first attempt, and how do I fix it? I've scoured the HttpServletRequest object in the debugger and I don't see any indication of the real request URI.

ClientAbortException on Jersey REST resource

I added a new method to my REST resource (Jersey). When I'm trying to test it I fails with:
ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine.
When I'm debugging it, I can see that my code gets to the return statement, by somewhere afterwards fail.
BTW, I have many other methods that works just fine, all return JSON objects.
This happened when I'm trying to call the new method from Jersey Client or simply from a web browser.
My code:
#GET
#Path("/metrics/samples")
#Produces(MediaType.APPLICATION_JSON)
public MetricSamples getFragmentMetricsSamples(#DefaultValue ("-1") #QueryParam ("from")long from, #DefaultValue ("-1") #QueryParam)
{
//Calling DAO code. Everything is OK here.
//I can even see in debug that that return statement is executed successfully.
return metricSamplesDataObject;
}
What can cause the connection to abort?
EDIT
I just came home and seems like the problem is relevant only while working at office.
So, the issue is that this specific method cause ClientAbortExcpetion at work only.
Could it be something related to the network security? Maybe because that amount of data?
Thanks

Verification failure while using openid4java for 'login with google'

I am using openid4java library for implementing the 'login with google' functionality in a spring-mvc application.
It works fine on my local tomcat server but on the remote server it has suddenly stopped working. It was working fine before there too.
After doing some logging in catalina.out I found that the verification of the response fails after google redirects to the return url
VerificationResult verification = openIdService.getConsumerManager().verify(
receivingURL.toString(),
response, discovered);
Identifier verified = verification.getVerifiedId(); //Null
The value of verified is null on the remote server. On local server its an uri
I am aware that while handling the response, ConsumerManager needs to be the same
instance used to place the authentication request.
The rest of the code is implemented as follows
There is an OpenIdController in which OpenIdService is Autowired.
The OpenIdServiceImpl implements OpenIdService and has the getConsumerManager method which returns the consumerManager instance.
In the construct of the OpenIdServiceImpl, an instance of ConsumerManager is created.
The actions that create the form for submission and handle the response are written in the
OpenIdController and access the consumerManager instance using the getConsumerManager method.
Edit:
I tried logging the Discovery information before the form submission and in the call back here it the output
Debugging OpenId: Discovered (before) OpenID2
OP-endpoint:https://www.google.com/accounts/o8/ud
ClaimedID:null
Delegate:null
Debugging OpenId: Discovered (after) OpenID2
OP-endpoint:https://www.google.com/accounts/o8/ud
ClaimedID:null
Delegate:nul
Am I doing anything wrong here ? But it works on local server!
Or something to do with tomcat configuration on the remote server ?
Any help is appreciated. I can post code if required.
Thanks.
I could resolve this problem by adding the following lines after creating an instance of ConsumerManager.
consumerManager.setAssociations(new InMemoryConsumerAssociationStore());
consumerManager.setNonceVerifier(new InMemoryNonceVerifier(5000));
consumerManager.setMinAssocSessEnc(AssociationSessionType.DH_SHA256);
I found it mentioned it in one of the comments to the SampleConsumer example here - http://code.google.com/p/openid4java/wiki/SampleConsumer
see response #3 from the bottom.
Haven't yet tried to figure out what it does, but hope its the right way to solve it :)

Categories