gpt4 book ai didi

java - 当 session 超时导致多部分表单 POST 中断时出现异常

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:16:44 24 4
gpt4 key购买 nike

我们有带 CAS 的 Spring 安全性(我不认为 CAS 是问题所在)。

问题不是 session 超时,而是如何处理此超时。

  1. 请求一个表单:GET/someform
  2. 填写多部分表单
  3. 重启服务器,或者删除JSESSIONID
  4. 提交表单:POST/someform(包含多部分数据)

  5. 用户被重定向到登录屏幕

  6. 登录用户被重定向到表单后:GET/someform
  7. spring 尝试重新发布已保存的表单(我认为它正在使用 DefaultSavedRequest)
  8. 它尝试调用映射到 POST/someform 的 Controller 函数,但请求不是多部分的
  9. 我们得到一个异常(exception):

Failed to invoke handler method [public org.springframework.web.servlet.ModelAndView com.xxx.xxx.XXXController.xxxPost(org.springframework.web.multipart.MultipartHttpServletRequest)]; nested exception is java.lang.IllegalStateException: Current request is not of type org.springframework.web.multipart.MultipartHttpServletRequest: com.secondmarket.web.UrlLowerCaseFilter$LowerCaseUrlServletRequestWrapper@77fb58b6

这是在 AccessDeniedException 发生时将请求保存到 session 的代码,它在 HttpSessionRequestCache 中(由 ExceptionTranslationFilter 调用):

public void saveRequest(HttpServletRequest request, HttpServletResponse response) {
if (!justUseSavedRequestOnGet || "GET".equals(request.getMethod())) {
DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, portResolver);

if (createSessionAllowed || request.getSession(false) != null) {
// Store the HTTP request itself. Used by AbstractAuthenticationProcessingFilter
// for redirection after successful authentication (SEC-29)
request.getSession().setAttribute(WebAttributes.SAVED_REQUEST, savedRequest);
logger.debug("DefaultSavedRequest added to Session: " + savedRequest);
}
}

}

如果请求是多部分请求,我如何编写 HttpSessionRequestCache 或 ExceptionTranslationFilter 以不保存请求?

最佳答案

通过修改 Controller 方法签名解决了问题。

以前,MultipartHttpServletRequest 在方法签名中。当 spring 从登录往返返回时,它尝试使用常规 HttpServletRequest 调用此方法,但失败了。

@RequestMapping(value = "/xxx", method = RequestMethod.POST)
public ModelAndView doAmlCheckPost(MultipartHttpServletRequest req) {
UserInfo currentUserInfo = UserInfo.getCurrentUserInfo(req);

MultipartFile someFile = req.getFile("someFile");

修复方法是使用常规 RequestMapping,并从 URL 中获取文件。如果请求不是 instanceof MultipartHttpServletRequest - 重定向到 GET 方法,它重新显示表单

@RequestMapping(value = "/xxx", method = RequestMethod.POST)
public ModelAndView doAmlCheckMultipartPost(HttpServletRequest req, @RequestParam(value = "someFile", required = false) MultipartFile someFile) {

if(!(req instanceof MultipartHttpServletRequest)){
return "redirect:/xxx";
}

所以现在的流程是这样的:

  1. 请求一个表单:GET/someform
  2. 填写多部分表单
  3. 重启服务器,或者删除JSESSIONID
  4. 提交表单:POST/someform(带有多部分数据)这里发生的是请求已保存在 session 中,但无法保存多部分数据,它是二进制的,无法序列化
  5. 用户被重定向到登录屏幕
  6. 登录用户被重定向到表单后:GET/someform
  7. spring 尝试重新发布保存的表单(我认为它正在使用 DefaultSavedRequest)SPRING 现在使用 HttpServletRequest 调用 POST 方法,而不是 MultipartHttpServletRequest。我们检测到它不是 MultipartHttpServletRequest 并重定向到 GET 页面,向用户重新显示表单

关于java - 当 session 超时导致多部分表单 POST 中断时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6140746/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com