I have added Struts2 interceptor, There I want to change calling action if some logic trigger. Currently I can change redirect JSP file after invoke the action. But I need to change the calling action before invoke the the action. Is there any way to invoke different action?
Thank You.
Your intercept method as per your comments would look something like this:
public String intercept(ActionInvocation actionInvocation) throws Exception {
final ActionContext actionContext = ActionContext.getContext();
final HttpServletRequest httpServletRequest = (HttpServletRequest) actionContext.get(HTTP_REQUEST);
HttpSession httpSession = httpServletRequest.getSession(false);
UserObject userObject = session.getAttribute("User"); //Check for user information, this is just a dummy
if(isSpecificUser(userObject)){
return "SpecificAction";
}
return actionInvocation.invoke();
}
SpecificAction should be present in your configuration file.
Related
Whenever i am intercepting request in struts2 interceptor getting httpmethod as GET. My requirement is to disable submission with GET httpmethod. please suggest.
try somthing like :
public String intercept(ActionInvocation actionInvocation) throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
if (!request.getMethod().equals("POST")){
return Action.ERROR;
}
return actionInvocation.invoke();
}
To get the HttpServletRequest in an interceptor I used below code:
HttpServletRequest request =(HttpServletRequest) ActionContext.getContext().get(HTTP_REQUEST);
I tried to implement ServletRequestAware in the interceptor but it did not worked.
Are there any better ways to get HttpServletRequest in an Interceptor ?!
You need to use ActionInvocation#getInvocationContext() to retrieve your request.
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext context = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context.get(ServletActionContext.HTTP_REQUEST);
// ...
}
The servlet stuff you could get referencing servletConfig interceptor. After this interceptor is invoked you could get servlet stuff from ServletActionContext.
HttpServletRequest request = ServletActionContext.getRequest();
use
final HttpServletRequest request = (HttpServletRequest) ActionContext.getContext()
.get(ServletActionContext.HTTP_REQUEST);
it worked for me
you will get ActionInvoction try getInvocationContext() it will return instance of "ActionContext" try .get(HTTP_REQUEST); on this.
or
use
ServletActionContext.getRequest()
I'm trying to use the authenticate() in a preRenderView listener method, in order to trigger authentication conditionally, depending on view parameters in the page. I tried adding a simple method:
#Named
#RequestScoped
public class PermissionBean implements java.io.Serializable {
public void preRender() {
System.out.println("IN PRERENDER");
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
try {
request.authenticate(response);
} catch (Exception e) { // may throw ServletException or IOException
e.printStackTrace();
}
}
The authenticate method itself doesn't throw an exception, it triggers the redirect to Login.xhtml as expected. However, I'm getting in my server log, I get this exception:
enter code here
INFO: IN PRERENDER
FINEST: GET /Login.xhtml previous[3]
INFO: Exception when handling error trying to reset the response.
java.lang.NullPointerException
at com.sun.faces.facelets.tag.jsf.core.DeclarativeSystemEventListener.processEvent(EventHandler.java:126)
at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2508)
at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2129)
at com.sun.faces.application.ApplicationImpl.invokeComponentListenersFor(ApplicationImpl.java:2077)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:286)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:244)
at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:670)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:108)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
So my request is not redirected to Login.xhtml.
My question is - is this something that should work within a JSF managed bean, or is it only legal outside of JSF request lifecycle? I tried calling authenticate() from a WebFilter, and it works as exptected.
Thanks,
Ellen
You need to tell JSF to not render the response which it was initially asked to do, whenever the request has been redirected. You can do that by checking if HttpServletRequest#authenticate() returns false and then invoke FacesContext#responseComplete() accordingly.
if (!request.authenticate(response)) {
FacesContext.getCurrentInstance().responseComplete();
}
Is there a way to know in Struts2 action's method if this is GET or POST request?
Your action should implent org.apache.struts2.interceptor.ServletRequestAware, so your action class should have something like
private HttpServletRequest httpRequest;
// ...
public void setServletRequest(HttpServletRequest request) {
this.httpRequest = request;
}
Then just do:
String method = httpRequest.getMethod() ;
You can use HTTPServletRequest.getMethod() to find out that and handle accordingly in action.
HTTPServletRequest.getMethod()
If you don't want to implement ServletRequestAware just for this, you can get the method with 1 line:
String method = ServletActionContext.getRequest().getMethod();
I have a method decorated with two custom ActionFilterAttribute.
[RequiresAuthentication(Order = 1)]
[ToonAction(Order = 2)]
public ActionResult Browse(...
RequiresAuthentication attribute is coming from this article
Inside RequiresAuthentication, on it's OnActionExecuting I do:
filterContext.HttpContext.Response.Redirect(loginUrl, true);
The line is get executed, and the arguments are all as expected. The problem is that after executing the line above, I get next attribute (ActionFilterAttribute) executed, as if redirect didn't work, it just continues executing the request, instead of simply redirecting browser.
Question: what else do I need to do to make the request handler
This is a complete method:
public override void OnActionExecuting(ActionExecutingContext filterContext) {
//redirect if not authenticated
var identity = filterContext.HttpContext.User.Identity;
if (!identity.IsAuthenticated) {
//use the current url for the redirect
string redirectOnSuccess = filterContext.HttpContext.Request.Url.PathAndQuery;
//send them off to the login page
string redirectUrl = string.Format("?ReturnUrl={0}", redirectOnSuccess);
string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;
filterContext.HttpContext.Response.Redirect(loginUrl, true);
// filterContext.Result = new HttpUnauthorizedResult();
// filterContext.HttpContext.Response.StatusCode = 0x191;
}
}
You want to set the Result on the filterContext to a RedirectResult, not do a redirect on the response.
filterContext.Result = new RedirectResult { Url = loginUrl };
EDIT: As #Hunter Daley suggests a better mechanism would be to use the AuthorizeAttribute instead if it works for you. If you do have authentication/authorization scenarios that the AuthorizeAttribute doesn't work for, it would probably be better to derive your custom attribute from it instead of the more generic ActionFilterAttribute. In any event, the correct technique is to set the Result rather than interact with the Response directly. You might want to look at the actual AuthorizeAttribute source at http://www.codeplex.com/aspnet for ideas.
I've got a sample of custom authorization code on my blog, http://farm-fresh-code.blogspot.com, too.
try adding the [Authorize] attribute to your Action methods instead
Add
filterContext.HttpContext.Response.Clear();
at first
and this at End :
filterContext.HttpContext.Response.End();
Hope this helps.
you can use
return RedirectToAction("Index", "Home/Login", new {area = "", returnURL = Request.Url.AbsolutePath});
to stop the current processing, redirect to the desired (login) page and quit the action.
the area route property is needed to get out of the current area if you are in any.
Add this code before you redirect the page.
filterContext.ExceptionHandled = true;