How to server-side forward a page request with Wicket 6 - wicket

In some circumstances, I have to pass a request to a Wicket page to another Wicket page on the server side, i.e. forward maintaining the URL in the browser address bar, but passing the page parameters to the second page.
Before Wicket 1.5, I could do
public MyPage(PageParameters params) {
// some logic here to decide whether and where to forward
setRedirect(false);
setResponsePage(MyOtherPage.class, params);
}
As setRedirect(boolean) no longer exists, is there a way to achieve a server-side forward in later Wicket versions?

A colleague just found the solution here:
http://mail-archives.apache.org/mod_mbox/wicket-users/201203.mbox/%3CCAMomwMr2fkO38E3d9RTk5TEmuf0Vx66F46F8eYs84Bb3bVtPgA#mail.gmail.com%3E
Now it is:
RequestCycle.get().scheduleRequestHandlerAfterCurrent(new RenderPageRequestHandler(new PageProvider(MyOtherPage.class, params), RenderPageRequestHandler.RedirectPolicy.NEVER_REDIRECT));
Scary piece of code... does not look elegant at all, but works.

On Wicket 6 you can redirect to another page in a simpler way, throwing RestartResponseAtInterceptPageException at any point in your page code:
throw new RestartResponseAtInterceptPageException(WicketPage.class)
It worked fine for me...

You should be able to simply do:
throw new RestartResponseException(MyOtherPage.class, params);

Related

How to redirect after logout from Laravel Middleware?

I'm writing some middleware in Laravel (version 8.0) which essentially checks for a deactivated organisation when an API route is called and it will log them out with the intention of redirecting to the sign in page with an appropriate message.
However, when the redirect runs it throws the following error:
The PUT method is not supported for this route. Supported methods: GET, HEAD.
The reason is because the API route being executed is a PUT method in this case so when it tries to run the redirect which expects a GET method it does not work.
Here is my middleware:
public function handle(Request $request, Closure $next): mixed
{
if (Auth::check() && Auth::user()) {
if($this->statusChecker::isServiceProviderDeactivated(Auth::user()['service_provider_id'])) {
auth()->guard('web')->logout();
(new SsoBroker())->logout();
return response()->redirectTo('/sign-in');
}
}
return $next($request);
}
The logout executes correctly (so if the user refreshes the page they are taken to the sign-in page) but the redirect does not work. I am not particularly experienced in writing middleware and I've done lots of research on this but not really finding any solutions. Since this site is a one-page react project the issue could lie there, but I am not sure. If anyone has any ideas I would appreciate it.
change the Route method instead of put to get/post
Route::get('/', [Auth::class, 'login'])

Wicket implement flash redirection

I would like to perform something like a flash redirection (not sure if it is really called flash redirection).
After a certain action like delete device, I am redirecting to the device list page.
Now, for the redirect URL... I am appending &sdr=true and it works.
The problem is... that parameter (&sdr=true) stays there even after just refreshing the page.
If I remember it correctly, when I do flash refresh... the parameter stays there but will disappear on refresh... or just good for one refresh only.
Below is my method for redirection:
public static void redirect(String redirectUrl) {
throw new RedirectToUrlException(redirectUrl);
}
now, how do I implement the flash redirection in wicket? I am using wicket 6 version.
Or... I would like the parameter &sdr=true be good only for 1 request. When the page is refreshed or reloaded... it should be gone.
Thanks :)
Sorry if this question is very easy, I am really new to wicket
May be there is another solution for your problem.
Wicket could be stateful, i.e. it can keep state between the pages navigation. So you can do:
setResponsePage(new SomePage(someState));
this way there is no need to pass anything in the url and SomePage's constructor can decide what to do with the passed state.
If you prefer to add request parameter in the url then you may use
PageParameters params = new PageParameters();
params.put("sdr", "true");
setResponsePage(SomePage.class, params);
In SomePage's constructor you will need to remove the sdr parameter from the passed PageParameters so that it is not rendered in all urls inside the page, e.g. in links, form action, etc.
But if you want the parameter to disappear in a page refresh/reload then you will need to make another redirect:
public SomePage(PageParameters params) {
super(params);
StringValue srdValue = params.get("srd");
if (!srdValue.isNull()) {
params.remove("srd");
// do something custom
throw new RestartResponseException(this);
// or throw new RestartResponseException(getPageClass(), params);
}
}

Play Framework: Don't change URL after form validation failed

In a plain Play application I have the following scenario.
A route file which looks like this:
GET /accounts/add controllers.Accounts.add()
POST /accounts controllers.Accounts.create()
The first route results in a view where I can add a new account. The form to submit the new account looks something like this:
#helper.form(action = routes.Accounts.create()) {...}
Now the controller binds the input to the form and checks for any validation errors:
public static Result create() {
Form<Account> form = Form.form(Account.class).bindFromRequest();
if (form.hasErrors()) {
return badRequest(views.html.account.add.render(form));
}
...
}
Now the thing is, the client will see the same view with some additional error messages. However, meanwhile the URL has changed from http://example.com/accounts/add to http://example.com/accounts.
If the client now reloads the browser this calls GET http://example.com/accounts (which isn't even mapped in this scenario - thus getting a 404 - Not Found).
Maybe it's just me but I find this kind of annoying and browsing some GitHub projects I couldn't find a good solution for this case.
Of cause things would be much simpler if the second route is rewritten to:
POST /accounts/add controllers.Accounts.create()
... in which case everything works fine. But from a REST point of view this doesn't feel good either. The same applies to update scenarios (having GET /accounts/:id/update vs. PUT /accounts/:id).
Is there a guide on how to handle this? Am I getting something wrong or is this no problem at all (from a pragmatic point of view)?
It's not possible to leave the previous URL because a request for a new address has already been made. A controller only provides response for a requested resource. To go to the previous URL you could only make a redirect in case of validation failure but you would lost errors that way so this is not a solution.
I suggest mapping both actions with the same URL. This way you would solve problem with the browser reload.
If you create a REST service for http clients that aren't browsers you will probably want to serve different response than a simple http page. The separation of actions for particular clients could be a good solution for keeping REST API clean and a browser user happy.

Simplest example for sending post data via links in Zend Framework

Starting with Zend and I´d like to know what is the simplest way of sending POST data to another page, not by forms, but by some link in my view instead. Thanks :)
You can't send POST data through a link. At least not through a normal link. Link can only carry GET data.
If you need to send POST over a link it's most certainly a design flaw.
If you're 100% sure, that you need it, you can do that using jQuery and onclick event. It`s not possible to do it without javascript. Other option would be to send it using form with hidden fields with single submit button visible - that would even work without javascript.
Normal hyperlinks in HTML are sent with GET requests and are not supposed to change the state of the resource being accessed. This is known as being idempotent. You can repeat the request over and over, and the result of each succeeding request to the same URL is the same as the first one.
POST requests don't have this restriction and are intended for when the user needs to change something (such as creating a new resource.)
It's not possible to send a POST request via a normal HTML link. And even if you find a way, it breaks an almost universal expectation that web users have. What are you trying to accomplish? Maybe there's a better way.
But to answer your question, you could use something like jQuery to capture the "click" event and make it do a POST request:
$('.my-link').click(function() {
var url = $(this).attr('href');
var data = {};
$.post(url, data, function() {
window.alert('success!');
});
return false;
});
If your URL has any query parameters, i.e. "?foo=bar&baz=bum", then you'd probably need to strip them off of the URL and pass them as a second parameter to the $.post() function. This is left as an exercise for the reader. ;-)

Issue with Telerik MVC grid using AJAX binding and the MVC Authorize attribute

I am using the Telerik MVC grid, together with AJAX binding to actions secured by [Authorize].
When the asp.net logged in session expires, if I trigger one of the grid actions, I get the following error message: "Error!The requested URL did not return JSON"
I want the ajax called actions to time out as a normal action would once the session has expired.
Any ideas? I've asked this a couple of times on the Telerik forums but have had no reply as yet.
TIA!
I finally found an answer on the telerik forums.
I customised the Grid Error client side event: link <--dead link
Edit: As the above link is dead, here is a code snippet. Hopefully it will help.
I used this on the Grid declaration:
.ClientEvents(events => events.OnError("onGridError"))
and this is the javascript function it calls which simply supresses the error and redirects to the login page:
function onGridError(e) {
e.preventDefault();
var xhr = e.XMLHttpRequest;
document.location.href = '../Account/Login';
}
Note: I don't think the middle line (var xhr...etc) actually does anything, looks redundant to me, just grabbed it from the codebase.