何时/什么JSESSIONID是创建a的条件?
是按域名吗?例如,如果我有一个Tomcat应用服务器,并且我部署了多个Web应用程序,JSESSIONID那么每个上下文(Web应用程序)是否会创建不同的Web应用程序,或者只要它们是同一个域,它是否可以跨Web应用程序共享?
更新:解决方案后问题.
通常,同步是在JVM内串行化并行请求,例如
private static final Object LOCK = new Object();
public void doSomething() {
...
synchronized(LOCK) {
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
在查看Web应用程序时,"JVM全局"范围上的某些同步可能会成为性能瓶颈,仅在用户的HttpSession范围内进行同步会更有意义.
以下代码是否可能?我怀疑同步会话对象是一个好主意,但听到你的想法会很有趣.
HttpSession session = getHttpServletRequest().getSession();
synchronized (session) {
...
}
Run Code Online (Sandbox Code Playgroud)
关键问题:对于处理来自同一用户的请求的所有线程
,是否保证会话对象是同一个实例?
看来会话对象本身并不总是相同,它依赖于servlet容器(Tomcat,Glassfish,...)的实现,并且该getSession()方法可能只返回一个包装器实例.
因此,建议使用存储在会话中的自定义变量作为锁定对象.
这是我的代码提案,欢迎提供反馈:
帮手类中的某个地方,例如MyHelper:
private static final Object LOCK = new Object();
public static Object getSessionLock(HttpServletRequest request, String lockName) {
if (lockName == null) lockName = "SESSION_LOCK";
Object result = request.getSession().getAttribute(lockName);
if (result == …Run Code Online (Sandbox Code Playgroud) 我有一个处理多部分表单帖子的servlet.帖子实际上是由嵌入页面的Flash文件上传组件制作的.在某些浏览器中,Flash生成的POST不包含JSESSIONID,这使得我无法在帖子期间从会话中加载某些信息.
Flash上传组件确实包含特殊表单字段中的cookie和会话信息.使用此表单字段,我实际上可以检索JSESSIONID值.问题是,我不知道如何使用此JSESSIONID值手动加载该特定会话.
编辑 -基于ChssPly76的解决方案,我创建了以下HttpSessionListener实现:
@Override
public void sessionCreated(final HttpSessionEvent se) {
final HttpSession session = se.getSession();
final ServletContext context = session.getServletContext();
context.setAttribute(session.getId(), session);
}
@Override
public void sessionDestroyed(final HttpSessionEvent se) {
final HttpSession session = se.getSession();
final ServletContext context = session.getServletContext();
context.removeAttribute(session.getId());
}
Run Code Online (Sandbox Code Playgroud)
这会将所有会话添加到ServletContext,作为由其唯一ID映射的属性.我可以在上下文中放置一个会话映射,但它似乎是多余的.请发表有关此决定的任何想法.接下来,我将以下方法添加到我的servlet以通过id解析会话:
private HttpSession getSession(final String sessionId) {
final ServletContext context = getServletContext();
final HttpSession session = (HttpSession) context.getAttribute(sessionId);
return session;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试将上传的多部分文件写入文件系统.我有一个名为audio的目录,它位于我的Web应用程序的根目录中(不在WEB-INF内部,但在它旁边,它可以像css和javascript一样公开访问).
我想将上传的文件写入该目录,但我似乎无法获得我需要的路径.我认为获得ServletContext()然后使用realPath()可能会工作,但我没有通过Spring控制器引用ServletContext.谢谢任何肝脏
@RequestMapping(value="/uploadSample")
public ModelAndView upload(HttpServletRequest request, HttpServletResponse response, @RequestParam("file") MultipartFile f) {
if (f == null) {
return new ModelAndView("upload", "msg", "The file is null.");
}
try {
// I need to set AUDIO_PATH to <webAppRoot>/audio
FileOutputStream file = new FileOutputStream(AUDIO_PATH + "/" + f.getOriginalFilename());
file.write(f.getBytes());
file.close();
}
catch (FileNotFoundException ex) {
Logger.getLogger(SampleUploadController.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(SampleUploadController.class.getName()).log(Level.SEVERE, null, ex);
}
return new ModelAndView("upload", "msg", "File ( " + f.getOriginalFilename() + ") successfully uploaded.");
}
Run Code Online (Sandbox Code Playgroud)
}
我有一些获取和设置会话属性的java代码:
Object obj = session.getAttribute(TEST_ATTR);
if (obj==null) {
obj = new MyObject();
session.setAttribute(obj);
}
Run Code Online (Sandbox Code Playgroud)
为了使这段代码成为线程安全的,我想将它包装在一个synchronized块中.但是我用什么作为锁定对象呢?使用会话是否有意义?
synchronized (session) {
Object obj = session.getAttribute(TEST_ATTR);
if (obj==null) {
obj = new MyObject();
session.setAttribute(obj);
}
}
Run Code Online (Sandbox Code Playgroud) 我正在考虑使用以下架构在同一服务器上部署多个(和不同的)Web应用程序:
www.mydomain.com/app1
www.mydomain.com/app2
这是一个好习惯吗?有什么建议?
java ×5
session ×3
servlets ×2
concurrency ×1
file-io ×1
httpsession ×1
java-ee ×1
jsessionid ×1
locking ×1
spring ×1