i am using jsf 2.0
i have question accoring to PreRenderView.
in my Bean i have method like
public void init() throws Exception
{
FacesContext.getCurrentInstance().getExternalContext().redirect("/To My Page");
if(!FacesContext.getCurrentInstance().isPostback())
{
System.out.println("Kshitij");
}
}
when this method is executing it is also printing "Kshitij" in servler log.
then redirecting to page.
why? i think it has to redirect to page first.
Why do you think that the actual redirect is performed first? The method has to finish running first before the server can ever continue the control over the request/response. It's impossible to pause code execution halfway and then continue code execution at exactly the same location in a brand new request and thread.
The redirect() call basically sets the Location response header. Only when the method has returned, the server will send the response and then the browser will send a new request on that location.
Add a return statement or an if/else if you want to skip the printing when you need to redirect.
if (youNeedToRedirect) {
FacesContext.getCurrentInstance().getExternalContext().redirect("/To My Page");
}
else {
if (!FacesContext.getCurrentInstance().isPostback()) {
System.out.println("Kshitij");
}
}
This all has got nothing to do with JSF or preRenderView. It's all just basic Java and HTTP.
Related:
java.lang.IllegalStateException: Cannot (forward | sendRedirect | create session) after response has been committed
Related
We having a specific problem in using Wicket 7.10, creating an Ajax-Response with multiple entries.
In our application, we are using onRequestHandlerResolved to do some initialization stuff and onRequestHandlerExecuted to save changes done on our data during requestHandlerExecutor.execute().
For this purpose, we have created an own AbstractRequestCycleListener which overwrites both methods and calls our specific code.
RequestCycle:
private void execute(IRequestHandler handler)
{
try
{
listeners.onRequestHandlerResolved(this, handler);
requestHandlerExecutor.execute(handler);
listeners.onRequestHandlerExecuted(this, handler);
}
catch (RuntimeException e)
{
}
}
Our problem is, that an Exception thrown in onRequestHandlerExecuted after requestHandlerExecutor.execute() has already created an ajax-response creates an invalid response:
Wicket.Ajax: Wicket.Ajax.Call.failure: Error while parsing response: Error: Invalid XML:
<?xml version="1.0" encoding="UTF-8"?>
<ajax-response>
<!-- Result of requestHandlerExecutor.execute() -->
</ajax-response>
<ajax-response>
<!—Redirect to specific Exception Page, result of onRequestHandlerExecuted -->
<redirect>
<![CDATA[./wicket/bookmarkable/our.package.ExceptionPage?locale=en]]>
</redirect>
</ajax-response>
To solve our problem, we tried to clear the existing Response during Exception in onRequestHandlerExecuted (RequestCycle.get().getResponse().reset()), but we are not able to clear the Response, created in requestHandlerExecutor.execute(), because Wicket uses HeaderBufferingWebResponse by default which did not allow to reset already created Response in encapsulated ServletWebResponse. Calling reset in HeaderBufferingWebResponse instead throws an IllegalStateException.
We think that the problem came from ServletWebResponse which simply adds multiple ajax-response entries to the HttpServletResponse which results in the mentioned, invalid XML.
ServletWebResponse:
#Override
public void sendRedirect(String url)
{
try
{
if (webRequest.isAjax())
{
/*
* usually the Ajax-Location header is enough and we do not need to the redirect url
* into the response, but sometimes the response is processed via an iframe (eg
* using multipart ajax handling) and the headers are not available because XHR is
* not used and that is the only way javascript has access to response headers.
*/
httpServletResponse.getWriter().write(
"<ajax-response><redirect><![CDATA[" + url + "]]></redirect></ajax-response>");
}
else { }
}
catch (IOException e) { }
}
How we could handle the problem when throwing an Exception in onRequestHandlerExecuted? And how is it possible, that code run after requestHandlerExecutor.execute(), redirects correctly to an Exception page?
How we can run specific code, after the request has been processed, is there maybe another way instead of overwriting onRequestHandlerExecuted?
For each Ajax request Wicket executes two request handlers:
ListenerInterfaceRequestHandler
AjaxRequestHandler
I assume your #onRequestHandlerExecuted is failing after the second one. This might be too late since the response is already generated and written.
You could check:
why does your listener fail after anything else has happened already?
what do you want your application to do when your listener fails?
can't the listener fail after the first handler already? why wait any longer?
I'm trying to create a middleware in Shelf that will inspect the request, and if certain values are found the request will be handled, otherwise it should be sent to the inner handler. Eg. I would like to inspect the Request.method.
Handler middleware(Handler innerHandler) {
return (Request req) async {
if(req.method == "GET" && req.headers["xxx"] == yyy) {
// Handle the request
...
}
else {
// This gives exception:
// Bad state: The 'read' method can only be called once on a shelf.Request/shelf.Response object.
return innerHandler(req);
}
}
The problem is that it is not possible to call the inner handler after the Request has been inspected. How do I go about inspecting it but still being able to send it along to the inner handler?
I haven't used it myself this way yet but I think you need to call change on the request, then you should be able to read and forward it. See also How to create/add middleware that adds default headers to each request
I have a JSF Phase Listerner that checks to see if the user is logged in, and if not, redirects them to the login page. This is working fine for non-ajax requests. However, if the user is on a page, in my case, one that has a primefaces data table, and clicks on a button that invokes an ajax request -- but their session has timed out -- the code gets executed that issues the redirect (using ExternalContext#redirect), however the user is not navigated to the login page.
Any idea why this is not working?
Here is my phase listener:
private static final String IS_LOGGED_IN_INDICATOR = "loggedIn";
private static final String LOGIN_PAGE = "/login.jsp";
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
public void beforePhase(PhaseEvent event) {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpSession session = (HttpSession)ec.getSession(false);
if (session==null || session.getAttribute(IS_LOGGED_IN_INDICATOR) == null) {
try {
ec.redirect(LOGIN_PAGE);
}
catch(IOException e) {
// log exception...
}
}
}
public void afterPhase(PhaseEvent event) {
// no-op
}
}
It failed because the ajax context is trying to obtain the render kit from the view root, while there is no view root at all. It has not been restored at that point yet. This resulted in a NullPointerException in PartialViewContext#createPartialResponseWriter(). This exception is in turn not been thrown, but instead been put in an ajax exception queue which is supposed to be handled by a custom ExceptionHandler. You apparently don't have any one. This exception is visible if you create/use such one like the FullAjaxExceptionHandler (see also this blog for more detail).
To fix the particular problem, do the job in afterPhase() instead. The view root is then fully restored and the ajax context can obtain the render kit from it in order to write a specialized XML response which instructs the JSF ajax engine in JavaScript to change the window location. Without ajax, a render kit was not necessary as a redirect is basically just a matter of setting a response header.
Whether the particular NullPointerException is in turn a bug in Mojarra or not is a different question which can better be posted in flavor of an issue report at their own issue tracker.
this is because you have to send a special response in XML for Ajax request in order to do redirect (check this answer) , I have implemented this in a Filter like this..
// Check if it's an Ajax Request
if ("partial/ajax".equals(((HttpServletRequest) request).getHeader("Faces-Request"))) {
//redirect
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version= \"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>",url);
you should port this to your Phase Listener.
In my grails application, failed login attemps get logged using spring security events as shown here http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/single.html#7.3%20Registering%20Callback%20Closures
My issue has to do with client ip retrieval. Normally, calling getRemoteAddress from details object of the event should do the job, but my case is that my application is behind a reverse proxy therefore i should get the ip from request header X-Forwarded-For.
Neither event object nor application context parameters of the closuse provide access to the request object. The global request object isn't available either.
Any ideas how to get access to headers or any other way to implement this functionality?
You can get it from RequestContextHolder, if it exists:
GrailsWebRequest request = RequestContextHolder.currentRequestAttributes()
request.getHeader("X-Forwarded-For")
Generally, as you probably know, it isn't considered a very good idea to access the web session from within Services. First of all, you break the abstraction and separation of service logic, and requests might not always be available or associated with the current thread. One way to access the session from a service is to encapsulate the HTTP session in the following manner:
class WebUtilService {
void withSession (Closure closure) {
try {
GrailsWebRequest request = RequestContextHolder.currentRequestAttributes()
GrailsHttpSession session = request.session
closure.call(session)
}
catch (IllegalStateException ise) {
log.warn ("No WebRequest available!")
}
}
}
and you would use it like this:
class MyService {
WebUtilService webUtilService
void doSomething() {
webUtilService.withSession { HttpSession session ->
log.info(session.myValue)
session.newValue = 'Possible, but should be exceptional'
}
}
}
where you could have access to the getHeader() method.
Disclaimer: the code is from Marc-Oliver Scheele's blog.
I am trying to provide a progress monitoring mechanism for a longish-running request implemented by an AsyncController. A web page invokes (via JQuery $.post) the asynchronous StartTask action on the following controller...
[NoAsyncTimeout]
public class TaskController: AsyncController
{
[HttpPost]
public void StartTaskAsync()
{
AsyncManager.OutstandingOperations.Increment();
Session["progress"] = "in progress";
Task.Factory.StartNew(DoIt);
}
public ActionResult StartTaskCompleted()
{
return Json(new {redirectUrl = Url.Action("TaskComplete", "First")});
}
private void DoIt()
{
try
{
// Long-running stuff takes place here, including updating
// Session["progress"].
}
finally
{
AsyncManager.OutstandingOperations.Decrement();
}
}
}
The same web page sets up a 2-second timer (via window.setInterval) to call the following controller (via JQuery $.getJSON) that has read-only access to the session...
[SessionState(SessionStateBehavior.ReadOnly)]
public class ProgressController: Controller
{
[HttpGet]
public ActionResult Current()
{
var data = Session["progress"];
return Json(data, JsonRequestBehavior.AllowGet);
}
}
The function invoked after getJSON returns updates a DIV to show the current progress. Ultimately the progress will be updated in the session by the 'long-running stuff takes place here' code, but as it is the call to ProgressController.Current() does not find any data in the session and always returns null.
I had assumed that JQuery AJAX requests sent from the same browser to the same IIS server would end up with the same session, but it seems not. Do I need to explicitly set the ASP.NET session key on these $.post and $.getJSON calls? Or is it just not possible to share session state between Controllers (even if one has R/O access) in this way (I can fall back to a slightly hacky solution with Application state and GUIDs).
That's normal behavior. Your StartTask action blocks until it completes. It doesn't return any response until the DoIt method has finished executing. I suppose that's why you are calling it with AJAX $.post. The problem is that while this method runs and writes to the session and all other requests from the same session will be queued by the ASP.NET engine. You cannot write and read from the session at the same time. You will have to find another thread-safe storage for the progress data other than the session.