Good way to handle sessions in Spring MVC - java

I was wondering if there is a better way to handle handling sessions than running this set of code through each one of my controller methods.
public ModelAndView addUser(#RequestParam("userid") String userId,
#RequestParam("passwd") String passwd,
#RequestParam("usrtype") String usrtype,
HttpSession session,
Model model ){
ModelAndView mav = new ModelAndView();
if ((String) session.getAttribute("userId") == null) {
model.addAttribute("msg", "Session was terminated.");
model.addAttribute("url", "/login");
mav.setViewName("redirect");
return mav;
}
...
How would one go about making this into reusable code?

There are multiple ways to optimize this:
Securing requests is something Spring Security is made for. Spring Security uses a Servlet filter to intercept (and deny) requests before they arrive in your controller. So you do not have to handle security related code in controller actions
If, for whatever reason, you can/want not use Spring Security you should have a look at Spring's MVC interceptions. In interceptors you can place code that need to be executed before and after controller actions.
If you always need to set the same Model attribute you can annotate methods with #ModelAttribute. This method will then be called for every request to populate your model, see ModelAttribute methods documentation. ControllerAdvice is similar, it is used if other classes than the controller should provide model information.

Related

intercept spring mvc controller call based on annotations

I have the following controller in spring MVC
#GetMapping("/id/kw")
public ModelAndView industryWater(HttpServletRequest request) {
return someMAV
}
I want to cut into the execution of the controller based on customized annotation
#GetMapping("/id/kw")
#WaterBefore
#WaterAfter
public ModelAndView industryWater(HttpServletRequest request) {
return someMAV
}
I can probably inject some thing using BEAN postProcessor, but I don't know how to hook my injected part with the controller execution. Also I need to access the context request mav when implementing my water aspect.
I researched a bit BeanPostProcessor, Interceptor, but didn't manage to connect all pieces.
I think you need to use AOP in Spring. that is very useful. it`s using transaction management and using logging etc.
Spring AOP (Aspect-oriented programming) framework is used to modularize cross-cutting concerns in aspects. If you want a more simple definition you can think of them as a Interceptor but with more options configurations possible. In Spring there are two different constructs that get called “interceptors”. First, there are Handler Interceptors, which are part of the Spring MVC framework and give you the ability to add interceptor logic to requests. But you also have Method Interceptors, which are part of the Spring AOP framework. These are much more general mechanism than Handler Interceptors, but also potentially more complex. In AOP terminology, such interceptors provide a means of coding the “aspects” you’re talking about.
Like this :
#Pointcut(" execution (* com.your.controller.industryWater(..))")
public void pointcutDemo() {}
#Before("pointcutDemo())")
public void logBefore(){ }
#After("pointcutDemo())")
public void logAfter(){ }
link : https://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/
https://www.journaldev.com/2583/spring-aop-example-tutorial-aspect-advice-pointcut-joinpoint-annotations
http://www.baeldung.com/spring-mvc-handlerinterceptor

Set something into Freemarker page by AOP in SpringMVC

To show the user's name on every Freemarker page, I could call model.addAttribute in every controller as below:
#RequestMapping(value = "index",method=RequestMethod.GET)
public String index(Model model) {
model.addAttribute("currentUser", App.getCurrentUser());
return "index";
}
#index.ftl
<div>${currentUser.userName}</div>
The calling would appear in everywhere of my code. It's really a nightmare. Is there any other way like AOP or Servlet Filter to set stuff into page?
You can use and interceptor for this, please check: http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor
This kind of information it would be better to keep it on a session scoped bean holding the user profile, rather than reloading it for every HTTP request.

Spring Security - Is there another way to intercept urls

So guys, there is a way to intercept urls, preventing non-logged users to acess, using spring security, but not at xml config or java based, something like #PreAuthorize on methods, and these ones return a view after they done something, but not like actions (add, delete).
Something like these:
#PreAuthorize("isAuthenticated")
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String home()
{
return "home";
}
What you want to do is possible, but it's less performance efficient and scatters the security code all over the controllers. To see the full capabilities of Expression-Based Access Control, check out this documentation

Spring MVC - Session Attributes - Should that be passed in all controllers as ModelAttribute

Am #SessionAttributes for maintaining SpringMVC.
Say, #SessionAttribute("user")
Currently am passing the object as ModelAttribute in all the controller, which needs to use the SessionObject "user" like
Class controller{
public ModelAndView method1(#ModelAttribute("user")){ }
public ModelAndView method2(#ModelAttribute("user")){ }
public ModelAndView method3(#ModelAttribute("user")){ }
public ModelAndView method4(#ModelAttribute("user")){ }
}
Is this the only way??
or
Is there any other way? such that I can have a base controller, which can return the session object by just extending the the base controller.
What I've been using in some of my projects is this:
String user = (String) hsr.getSession().getAttribute("user");
If you're looking for some sort of authentication I suggest you start using spring security or other authentication mechanisms that can filter out pages according to roles or authentication status.
Not sure what your exact requirement is, but what about creating a filter/interceptor that reads the value from session and stores it in a ThreadLocal that can be accessed by controllers later
The controllers that need to access #SessionAttributes you need to add the annotation as shown below.
#Controller
#SessionAttributes({"user"})
public class Controller {
.............
}
HTH

Where to store request specific values in Spring MVC?

I'm using Spring MVC and I want to store request specific values somewhere so that they can be fetched throughout my request context. Say I want to set a value into the context in my Controller (or some sort of handler) and then fetch that value from some other part of the Spring request/response cycle (could be a view, view resolver, interceptor, exception handler, etc)... how would I do that?
My question is:
Does Spring MVC already provide a method to do what I described above?
If Spring doesn't have this functionality, any ideas on the best way to do this (by extending something maybe)?
Thanks!
If you need to pass an object from your controller to view, you can use Spring's ModelMap.
#RequestMapping("/list")
public String list(ModelMap modelMap) {
// ... do foo
modelMap.addAttribute("greeting", "hello");
return viewName;
}
on your view:
<h1>${greeting}</h1>
You could use sessionAttributes.
Session Attributes
I took the latest version of the api (3.1) since you didn't mention your version of spring.

Categories