本章将对 FlashMapManager 接口进行分析, FlashMapManager作用是在redirect中传递参数,默认SessionFlashMapManager通过session实现传递。在FlashMapManager接口中定义了两个方法,具体代码如下:
public interface FlashMapManager {
@Nullable
FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);
void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
}
下面对方法进行说明:
本节将搭建一个用于FlashMapManager 源码分析和调试的测试环境,首先需要在applicationContext.xml文件中添加一个FlashMapManager 的实现类,具体代码如下:
<bean id="flashMapManager" class="org.springframework.web.servlet.support.SessionFlashMapManager"/>
在完成该配置后测试环境就搭建完成,下面可以请求项目中的任意一个接口,如果没有可以定义一个接口,具体定义如下:
@Controller
@CrossOrigin
public class HelloController {
@GetMapping("/demo")
public String demo(HttpServletRequest req) {
FlashMap flashMap = (FlashMap) req.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE);
flashMap.put("name", "name");
return "hello";
}
}
本节将对FlashMapManager对象的初始化相关内容进行分析,具体处理代码如下:
private void initFlashMapManager(ApplicationContext context) {
try {
this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
if (logger.isTraceEnabled()) {
logger.trace("Detected " + this.flashMapManager.getClass().getSimpleName());
}
else if (logger.isDebugEnabled()) {
logger.debug("Detected " + this.flashMapManager);
}
}
catch (NoSuchBeanDefinitionException ex) {
// We need to use the default.
this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class);
if (logger.isTraceEnabled()) {
logger.trace("No FlashMapManager '" + FLASH_MAP_MANAGER_BEAN_NAME +
"': using default [" + this.flashMapManager.getClass().getSimpleName() + "]");
}
}
}
在这段代码中只提供了一种方式获取FlashMapManager 对象,具体方式是通过名称+类型进行获取,这个获取方式对应了前文对于测试环境搭建中的配置信息:
<bean id="flashMapManager" class="org.springframework.web.servlet.support.SessionFlashMapManager"/>
通过调试初始化方法可以看到FlashMapManager的数据信息如下:
本节将对SessionFlashMapManager类进行分析,主要关注三个方法retrieveFlashMaps、updateFlashMaps和getFlashMapsMutex。下面先对retrieveFlashMaps方法进行分析,该方法的完整代码如下:
@Override
@SuppressWarnings("unchecked")
@Nullable
protected List<FlashMap> retrieveFlashMaps(HttpServletRequest request) {
HttpSession session = request.getSession(false);
return (session != null ? (List<FlashMap>) session.getAttribute(FLASH_MAPS_SESSION_ATTRIBUTE) : null);
}
在这段代码中可以明确提取FlashMap对象的方式是通过Session中的FLASH_MAPS_SESSION_ATTRIBUTE属性值进行提取。其次对updateFlashMaps方法进行分析,该方法的完整代码如下:
@Override
protected void updateFlashMaps(List<FlashMap> flashMaps, HttpServletRequest request, HttpServletResponse response) {
WebUtils.setSessionAttribute(request, FLASH_MAPS_SESSION_ATTRIBUTE, (!flashMaps.isEmpty() ? flashMaps : null));
}
在这段代码中可以明确它的保存操作,具体是将flashMaps对象放入到Session中的FLASH_MAPS_SESSION_ATTRIBUTE属性中。最后对getFlashMapsMutex方法进行分析,该方法的完整代码如下:
@Override
protected Object getFlashMapsMutex(HttpServletRequest request) {
return WebUtils.getSessionMutex(request.getSession());
}
在这段代码中主要目的是获取Session中的mutex对象。
本节将对AbstractFlashMapManager类进行分析,首先对retrieveAndUpdate方法进行分析,完整代码如下:
@Override
@Nullable
public final FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response) {
List<FlashMap> allFlashMaps = retrieveFlashMaps(request);
if (CollectionUtils.isEmpty(allFlashMaps)) {
return null;
}
List<FlashMap> mapsToRemove = getExpiredFlashMaps(allFlashMaps);
FlashMap match = getMatchingFlashMap(allFlashMaps, request);
if (match != null) {
mapsToRemove.add(match);
}
if (!mapsToRemove.isEmpty()) {
Object mutex = getFlashMapsMutex(request);
if (mutex != null) {
synchronized (mutex) {
allFlashMaps = retrieveFlashMaps(request);
if (allFlashMaps != null) {
allFlashMaps.removeAll(mapsToRemove);
updateFlashMaps(allFlashMaps, request, response);
}
}
}
else {
allFlashMaps.removeAll(mapsToRemove);
updateFlashMaps(allFlashMaps, request, response);
}
}
return match;
}
在该方法中主要调用逻辑如下:
本章围绕FlashMapManager 接口出发,介绍了FlashMapManager 接口的作用和两个实现类它们具体实现过程,此外对一些常见的FlashMapManager实现类做了相关测试用例作为源码调试的基础。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。