Spring MVC自定义范围bean

编程入门 行业动态 更新时间:2024-10-13 14:23:52
本文介绍了Spring MVC自定义范围bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想创建自己的自定义范围bean,它将使用HTTP会话(一种Flash范围)。

I would like to create my own custom scope bean which will use HTTP session (kind of Flash scope).

根据Spring手册,我需要实现org.springframework.beans.factory.config.Scope接口

According to Spring Manual I need to implement org.springframework.beans.factory.config.Scope interface

public class CustomScope implements Scope { @Override public Object get(String arg0, ObjectFactory<?> arg1) { // TODO Auto-generated method stub return null; } @Override public String getConversationId() { // TODO Auto-generated method stub return null; } @Override public void registerDestructionCallback(String arg0, Runnable arg1) { // TODO Auto-generated method stub } @Override public Object remove(String arg0) { // TODO Auto-generated method stub return null; } @Override public Object resolveContextualObject(String arg0) { // TODO Auto-generated method stub return null; } }

我的问题是如何获取内部的HTTP会话这豆子?我理解如果我在ServletContext范围内创建bean,我会实现ServletContextAware接口。

My question is how can I obtain HTTP session inside of this bean? I understand that if I was creating bean in ServletContext scope I would implement ServletContextAware interface.

请帮助:)

推荐答案

我希望它对未来的人有用,所以我想分享一下。

I hope it will be useful for someone in the future, so I would like to share it.

我做了一些研究在它上面发现,遗憾的是,它无法获得Spring MVC的HTTP Session。

I made some reserch on it and have found that unfortunately, it is impossible to get HTTP Session for Spring MVC.

我的目的是使用PRG模式为我的Spring MVC控制器实现Flash Scope。

My purpose was Flash Scope implementation for my Spring MVC Controller using PRG pattern.

在Spring进行更多研究论坛我找到了使用HandlerInterceptor的方法。

Making more research in Spring Forum I've found the way to do it using HandlerInterceptor.

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.util.*; import java.util.Map.Entry; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class FlashScopeInterceptor implements HandlerInterceptor { public static final String DEFAULT_ATTRIBUTE_NAME = "flashScope"; public static final String DEFAULT_SESSION_ATTRIBUTE_NAME = FlashScopeInterceptor.class.getName(); public static final int DEFAULT_RETENTION_COUNT = 2; private String sessionAttributeName = DEFAULT_SESSION_ATTRIBUTE_NAME; private String attributeName = DEFAULT_ATTRIBUTE_NAME; private int retentionCount = DEFAULT_RETENTION_COUNT; /** * Unbinds current flashScope from session. Rolls request's flashScope to * the next scope. Binds request's flashScope, if not empty, to the session. * */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { if (request.getSession( false ) != null) { request.getSession().removeAttribute( this.sessionAttributeName ); } Object requestAttribute = request.getAttribute( this.attributeName ); if (requestAttribute instanceof MultiScopeModelMap) { MultiScopeModelMap attributes = (MultiScopeModelMap) requestAttribute; if (!attributes.isEmpty()) { attributes.next(); if (!attributes.isEmpty()) { request.getSession( true ).setAttribute( this.sessionAttributeName, attributes ); } } } } /** * merge modelAndView.model['flashScope'] to current flashScope */ @Override public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (modelAndView != null) { Map<String, Object> modelFlashScopeMap = null; for (Iterator<Entry<String, Object>> iterator = ((Map<String, Object>) modelAndView.getModel()).entrySet() .iterator(); iterator.hasNext();) { Entry<String, Object> entry = iterator.next(); if (this.attributeName.equals( entry.getKey() ) && entry.getValue() instanceof Map) { if (modelFlashScopeMap == null) { modelFlashScopeMap = (Map) entry.getValue(); } else { modelFlashScopeMap.putAll( (Map) entry.getValue() ); } iterator.remove(); } else if (entry.getKey().startsWith( this.attributeName + "." )) { String key = entry.getKey().substring( this.attributeName.length() + 1 ); if (modelFlashScopeMap == null) { modelFlashScopeMap = new HashMap<String, Object>(); } modelFlashScopeMap.put( key, entry.getValue() ); iterator.remove(); } } if (modelFlashScopeMap != null) { MultiScopeModelMap flashScopeMap; if (request.getAttribute( this.attributeName ) instanceof MultiScopeModelMap) { flashScopeMap = (MultiScopeModelMap) request.getAttribute( this.attributeName ); } else { flashScopeMap = new MultiScopeModelMap( this.retentionCount ); } flashScopeMap.putAll( modelFlashScopeMap ); request.setAttribute( this.attributeName, flashScopeMap ); } } } /** * binds session flashScope to current session, if not empty. Otherwise cleans up empty * flashScope */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession( false ); if (session != null) { Object sessionAttribute = session.getAttribute( this.sessionAttributeName ); if (sessionAttribute instanceof MultiScopeModelMap) { MultiScopeModelMap flashScope = (MultiScopeModelMap) sessionAttribute; if (flashScope.isEmpty()) { session.removeAttribute( this.sessionAttributeName ); } else { request.setAttribute( this.attributeName, flashScope ); } } } return true; } }

现在MultiScopeModelMap.java

Now MultiScopeModelMap.java

import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Set; import org.apachemons.collections.map.CompositeMap; import org.apachemons.collections.map.CompositeMap.MapMutator; public class MultiScopeModelMap extends CompositeMap implements Serializable, MapMutator { public MultiScopeModelMap(int num) { super(); setMutator( this ); for(int i = 0; i < num; ++i) { addComposited( new HashMap() ); } } /** Shadows composite map. */ private final LinkedList<Map> maps = new LinkedList<Map>(); @Override public synchronized void addComposited( Map map ) throws IllegalArgumentException { super.addComposited( map ); this.maps.addLast( map ); } @Override public synchronized Map removeComposited( Map map ) { Map removed = super.removeComposited( map ); this.maps.remove( map ); return removed; } /** * Starts a new scope. * All items added in the session before the previous session are removed. * All items added in the previous scope are still retrievable and removable. */ public void next() { removeComposited( this.maps.getFirst() ); addComposited( new HashMap() ); } public Object put( CompositeMap map, Map[] composited, Object key, Object value ) { if(composited.length < 1) { throw new UnsupportedOperationException("No composites to add elements to"); } Object result = map.get( key ); if(result != null) { map.remove( key ); } composited[composited.length-1].put( key, value ); return result; } public void putAll( CompositeMap map, Map[] composited, Map mapToAdd ) { for(Entry entry: (Set<Entry>)mapToAdd.entrySet()) { put(map, composited, entry.getKey(), entry.getValue()); } } public void resolveCollision( CompositeMap composite, Map existing, Map added, Collection intersect ) { existing.keySet().removeAll( intersect ); } @Override public String toString() { return new HashMap(this).toString(); } }

用法:

@RequestMapping(value="/login.do", method=RequestMethod.POST) public ModelAndView login(@Valid User user){ ModelAndView mv = new ModelAndView("redirect:result.html"); if (authService.authenticate(user.getUserName(), user.getPassword())) mv.addObject("flashScope.message", "Success"); //else mv.addObject("flashScope.message", "Login Failed"); return mv; } @RequestMapping(value ="/result.html", method=RequestMethod.GET) public ModelAndView result(){ ModelAndView mv = new ModelAndView("login/loginAction"); return mv; }

在JSP中使用非常简单:

In JSP the usage is very simple:

${flashScope.message}

此外,您需要将FlashScopeInterceptor类配置为拦截器。

In addition you need to configure FlashScopeInterceptor class as interceptor.

<bean id="flashScopeInterceptor" class="x.y.z.FlashScopeInterceptor" /> <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <list><ref bean="flashScopeInterceptor"/></list> </property> </bean>

更多推荐

Spring MVC自定义范围bean

本文发布于:2023-11-28 12:36:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1642422.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   Spring   MVC   bean

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!