How to Use Parameters, Request and Session Objects Present in Actioncontext

How to use parameters, request and session objects present in ActionContext?

In Struts2, Session Map and Request Map are wrappers for the underlying HttpServletRequest and Session objects.

If you only need to access attributes, use the wrappers.

Use ActionContext to get them (both the wrappers and the underlying HTTP objects) only if you are inside an Interceptor or a POJO.

If you are inside an Action, the best practice is to implement an Interface that will automatically populate your Action's object:


To get the Request Map wrapper, use RequestAware

public class MyAction implements RequestAware {
private Map<String,Object> request;

public void setRequest(Map<String,Object> request){
this.request = request;
}
}

To get the Session Map wrapper, use SessionAware

public class MyAction implements SessionAware {
private Map<String,Object> session;

public void setSession(Map<String,Object> session){
this.session = session;
}
}

To get the underlying HttpServletRequest and HttpSession objects, use ServletRequestAware:

public class MyAction implements ServletRequestAware {
private javax.servlet.http.HttpServletRequest request;

public void setServletRequest(javax.servlet.http.HttpServletRequest request){
this.request = request;
}

public HttpSession getSession(){
return request.getSession();
}
}

That said, the standard data flow between JSP pages and Actions, or Actions and Actions, is obtained through Accessors / Mutators, better known as Getters and Setters. Don't reinvent the wheel.

Best practice to implement HttpServletRequest in Struts2?

I couldn't see (or find documentation about) the benefits of 2. vs 1.

So why should I prefer

public class MyAction extends ActionSupport implements ServletRequestAware {

private HttpServletRequest request;

@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}

When is worth enough

HttpServletRequest request = ServletActionContext.getRequest(); 

How to use Application scope variable in custom interceptor?

ApplicationAware is an interface used to inject a global map into actions, not interceptors:

Actions that want to be aware of the application Map object should implement this interface. This will give them access to a Map where they can put objects that should be available to other parts of the application.

There are mutliple ways to achieve what you want, but I'm pretty sure it's not what you need. Why on earth are you putting login informations into a global objects ? Just write to and read from the Session, that's what you need.

Best and recommended approach to get session in struts2?

Implementing SessionAware is preferred although you can access the session in other ways you stated too.

By implementing SessionAware you give struts2 a chance to inject the session attributes (Which is the map) into your action. This keeps your code clean from coupling to underlying servlet context and also makes testing easier since you can pass any map object to your action with desired attributes.
Also any change made to this session map will be reflected on the real session object.

Inserting a variable into Session Map in Struts2

Do not reinvent the wheel.

Struts2 already uses a SessionMap wrapper object, among the others.

Simply implements SessionAware interface, and provide a setter for your object; then put and retrieve your object from that map, that will be automatically handled by all your actions implementing SessionAware interface:

public class FirstAction implements SessionAware {

private Map<String,Object> session;
public void setSession(Map<String,Object> session){
this.session = session;
}

private String username; /* with Getter and Setter */

public String execute(){
session.put("uname", username);
return SUCCESS;
}
}

public class SecondAction implements SessionAware {

private Map<String,Object> session;
public void setSession(Map<String,Object> session){
this.session = session;
}

public String execute(){
System.out.println(session.get("uname"));
return SUCCESS;
}
}

That said, it would be better to implement SessionAware only from a parent Action, to avoid redundancy, and to extend that Action from all the actions that need to access the Session Map.

Accessing post or get parameters in custom authorization MVC4 Web Api

Due to its nature the AuthoriseAttribute looks like it is called in the pipeline before the model binders and parameter bindings have run. You also run into issues when you access the Request.Content and read from it... this can only be done once and if you are going to try it in your auth attribute you may break the mediaTypeFormater...

in WebAPI, the request body (an HttpContent) may be a read-only, infinite, non-buffered, non-rewindable stream.

Update
There are different ways of specifying the execution context... http://msdn.microsoft.com/en-us/library/system.web.http.filters.filterscope(v=vs.108).aspx. The AuthoriseAttribute is "Global" and therefore it is hit too early to access the action information.

Given you want access to the model and parameters you can change your approach slightly and use an OnActionExecuting filter ("Action" filter scope) instead and throw a 401 or 403 based on your validation.

This filter is called later in the execution process and you therefore have full access to the bound data.

Very simple example below:

public class ApiAuthorizationFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
Foo model = (Foo)actionContext.ActionArguments["model"];
string param1 = (string)actionContext.ActionArguments["param1"];
int param2 = (int)actionContext.ActionArguments["param2"];

if (model.Id != "1")
throw new HttpResponseException(System.Net.HttpStatusCode.Forbidden);

base.OnActionExecuting(actionContext);
}
}

Example controller:

public class Foo
{
public string Id { get; set; }
public DateTime Time { get; set; }
}

public class FoosController : ApiController
{
// PUT api/foos/5
[ApiAuthorizationFilter]
public Foo Put(int id, Foo model, [FromUri]string param1 = null, int? param2 = null)
{
return model;
}
}

What the other answers were saying.... they are right you can, if you can access all you need on the URL, get at stuff via the request; however, I think the model and the request content should be left alone:

var queryStringCollection = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);

//example for param1
string param1 = queryStringCollection["param1"];
//example for param2
int param2 = int.Parse(queryStringCollection["param2"]);
//Example of getting the ID from the URL
var id = actionContext.Request.RequestUri.Segments.LastOrDefault();

Struts setSesssion() is not working

You are missing the session is a different object in both cases. You don't need to use scriptlets in the code. If you want to put something to the session you should get the session map from the action context

Map<String, Object> session = ActionContext.getContext().getSession();
session.put("username", username);
session.put("role", 1);
return Action.SUCCESS;

or use servlet session directly

HttpSession session = ServletActionContext.getRequest().getSession(); 
session.setAttribute("username", username);
session.setAttribute("role", 1);
return Action.SUCCESS;

But the first case is preferable, due to it's supported by the framework.



Related Topics



Leave a reply



Submit