Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing session variables outside servlet

I'm working on a java webapp where I need to access records from database based on user login id.I set the login details in session variable after successful login.

I want to do is something like this

Select * from proj_recs where user_id= user_id (from session)

Right now I'm passing username as a parameter, but I believe it's not a good practice. Is there a better way of accessing session variables outside servlet ?

Servlet

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        User user = (User) request.getSession().getAttribute("userInfo");

        System.out.println(user);

        if(user != null){
            Gson gson = new Gson();
            returnJsonResponse(response,gson.toJson(user));
            return;
        }
}

In data layer package

public Accrual getAccruals(String accrualID,String userid) throws AccrualNotFoundException{

    String sql = Select * from db_acc where acc_id= accrualID and user_id=userid;

}

The problem is I have to modify all my methods with userid. Is there a way I can set user details into some static class and access the details where ever i want in the application without modifying the method signature? But I believe static classes are share between different user requests.

like image 892
Ravi Avatar asked Nov 01 '22 21:11

Ravi


2 Answers

The solution that you are looking for is Thread Local (google it). It allows you to access thread-specific data using static method.

You can start reading http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/. Using examples from there, you need to create:

public class MyThreadLocal {

    public static final ThreadLocal userThreadLocal = new ThreadLocal();

    public static void set(User user) {
        userThreadLocal.set(user);
    }

    public static void unset() {
        userThreadLocal.remove();
    }

    public static User get() {
        return userThreadLocal.get();
    }
}

in your servlet, do this:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    User user = (User) request.getSession().getAttribute("userInfo");
    MyThreadLocal.set(user);
    try {
       // call data layer
    } finally {
        MyThreadLocal.unset();
    }
}

in your data layer, you can retrieve the user by doing this:

public void dataLayerMethod(ExistingParameters parameters) {
    User user = MyThreadLocal.get();
}

Notice that you don't need to change the method signature of the data layer.

Thread Local is a bit confusing at first, but you will get familiar very quickly once you read the article.

like image 153
fajarkoe Avatar answered Nov 11 '22 06:11

fajarkoe


I think u can easily use

SecurityUtils.getSubject().getSession().getAttribute("userInfo");

so no need to change signature. This way you can use shiros inbuilt utility instead of relying on your own logics and probabilties.

public Accrual getAccruals(String accrualID) throws AccrualNotFoundException{
    User user = (User) SecurityUtils.getSubject().getSession().getAttribute("userInfo");
    String userid= user.getUserId();
    String sql = Select * from db_acc where acc_id= accrualID and user_id=userid;

}
like image 33
Dev Avatar answered Nov 11 '22 08:11

Dev