I'm trying to develop a Spring MVC application, now I encounter a question. When login successful I add the User entity to session and call http://localhost:8080/user
to get the session user. Everything is OK here. But if I call the URL like this http://localhost:8080/user?username=testuser
then the session user's username will change to testuser. What should I do that just get current user from session?
The code likes below
Entity:
@Entity
public class User {
private Long id;
private String username;
// ...Getter and Setter...
}
Controller:
@Controller
@RequestMapping("user")
@SessionAttributes("current_user")
public class UserController {
@RequestMapping(method=RequestMethod.GET)
@ResponseBody
public User testSession(@ModelAttribute("current_user") User user) {
return user;
}
}
Response of http://localhost:8080/user
[{"id":1,"username":"aaa111"}]
Response of http://localhost:8080/user?username=testuser
; it should be same as above, but is
[{"id":1,"username":"testuser"}]
The @SessionAttributes
annotation isn't intended for this. Its intend is to store objects in the session during http requests. Imagine a lengthy database call to retrieve an object you don't want to retrieve this object each time but probably reuse an existing one. The object is to be intended to be used as a @ModelAttribute
, this annotation indicates that you want to use this object for binding (ie you have a form to change attributes of the object). When you are finished with the editing of the object you should make this clear by calling setComplete()
on the SessionStatus
object. See also here .
You want to store an object in the session and retrieve it when you need it. For this use the HttpSession
in the normal way of calling setAttribute
and getAttribute
. To obtain the current HttpSession
you can simply add a method argument of the type HttpSession
and it will be injected for you. (See here for a list of supported method arguments).
public void myRequestHandlingMethod(HttpSession session) {
User currentUser = (User) session.getAttribute("currentUser");
}
Or as you are already using Spring you could use the WebUtils
for convenience. You can use the getSessionAttribute
or getRequiredSessionAttribute
methods to obtain the value from the session.
public void myRequestHandlingMethod(HttpServletRequest request) {
User currentUser = (User) WebUtils.getSessionAttribute("currentUser", request)
}
Another solution would be to extend Spring MVC. Spring MVC uses a HandlerMethodArgumentResolver
to handle all the different types of method arguments. This mechanism is pluggable. You could create an annotation @CurrentUser
and create a CurrentUserHandlerMethodArgumentResolver
that will retrieve the user from the session and injects it in that place. You could then simply add your current user to your method signature.
public void myRequestHandlingMethod(@CurrentUser User user) { ... }
Configure the custom argument resolver
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.yourcomponany.app.web.CurrentUserHandlerMethodArgumentResolver />
</mvc:argument-resolvers>
</mvc:annotation-driven>
It also looks like you are rolling your own security framework, which I would advice against. Instead I would suggest using Spring Security instead. Advantage of this is that this provides integration with the Servlet API allowing for retrieval of the current Principal
by either doing it yourself ( request.getUserPrincipal()
) or simply adding a method argument of the type java.security.Principal
. It also comes with a custom HandlerMethodArgumentResolver
which allows you to obtain the current Spring Security Authentication
object.
try to get session value in controller from servlet request like below
@Controller
@RequestMapping("user")
@SessionAttributes("current_user")
public class UserController{
@RequestMapping(method=RequestMethod.GET)
@ResponseBody
public User testSession(HttpServletRequest request){
//false means do not create new session
HttpSession session = request.getSession(false);
return session != null?session.getAttribute("current_user"):null;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.