java 网站用户在线和客服聊天

2023-05-16


注:本文来源于《java 网站用户在线和客服聊天》



这是应用到项目中的一个例子。

实现原理是将信息存储到Application域里面。然后使用Struts2 Action 用json格式的数据进行前后台交互。

截图:

前台用户界面:

20130521081322386

后台客服界面:

20130521081348963

编辑框采用的Ueditor 可以发送图片表情文字格式、涂鸦。。。。等等!功能十分的强大!

代码部分:

20130521081505375

用到了两个Action,分别为用户和管理员服务。

Struts.xml


<!-- 聊天功能实现  -->
	<package name="chat" extends="struts-default,json-default">
		<!-- 用户发送消息  -->
		<action name="chatMessageSend" class="com.shop.chat.MessageAction" method="send">
			<result name="success" type="json"></result>
		</action>

		<!-- 用户接受消息  -->
		<action name="chatMessageGet" class="com.shop.chat.MessageAction">
			<result type="json"></result>
		</action>

		<!-- 管理员获取消息  -->
		<action name="adminMessageGet" class="com.shop.chat.AdminMessageAction">
			<result name="success" type="json"></result>
		</action>

		<!-- 管理员发送消息到用户  -->
		<action name="adminMessageSend" class="com.shop.chat.AdminMessageAction" method="send">
			<result type="json"></result>
		</action>

		<!-- 管理员列表  -->
		<action name="adminList" class="com.shop.chat.AdminListAction">
			<result type="json"></result>
		</action>

	</package>
  


Java 类:


package com.shop.chat.admin;

import java.util.ArrayList;
import java.util.List;

import com.shop.bean.Admin;

/**
 * 存放当前已经登陆的管理员列表
 * @author Pan
 *
 */
public class AdminList {

	private List<Admin> list=new ArrayList<Admin>();
	public AdminList(){

	}

	/**
	 * 增加Admin对象
	 * @param admin
	 */
	public void save(Admin admin){
		if(list.indexOf(admin)==-1){
			list.add(admin);
		}
	}

	/**
	 * 得到所有Admin
	 * @return
	 */
	public List<Admin> getList(){
		return list;
	}
}  




package com.shop.chat.admin;

import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;

import com.shop.bean.Admin;

/**
 * admin列表服务
 * @author Pan
 *
 */
public class AdminListServler {

	private AdminList list;

	public AdminListServler(HttpSession session){
		ServletContext context=session.getServletContext();
		list=(AdminList)context.getAttribute("adminlist");
		if(list==null){
			list=new AdminList();
			context.setAttribute("adminlist", list);
		}
	}
	/**
	 * add an admin to the list
	 * @param admin
	 */
	public void save(Admin admin){
		list.save(admin);
	}

	/**
	 * get all admin object
	 * @return arraylist
	 */
	public List<Admin> getList(){
		return list.getList();
	}
}
  

package com.shop.chat.admin;

import java.sql.Timestamp;

public class AdminSimplify {

	private Integer id;
	private String adminName;
	private String adminPass;
	private String nickName;
	private String head;
	private Timestamp addTime;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getAdminName() {
		return adminName;
	}
	public void setAdminName(String adminName) {
		this.adminName = adminName;
	}
	public String getAdminPass() {
		return adminPass;
	}
	public void setAdminPass(String adminPass) {
		this.adminPass = adminPass;
	}
	public String getNickName() {
		return nickName;
	}
	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	public String getHead() {
		return head;
	}
	public void setHead(String head) {
		this.head = head;
	}
	public Timestamp getAddTime() {
		return addTime;
	}
	public void setAddTime(Timestamp addTime) {
		this.addTime = addTime;
	}

}
  

package com.shop.chat;

import java.util.ArrayList;
import java.util.List;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.shop.bean.Admin;
import com.shop.chat.admin.AdminListServler;
import com.shop.chat.admin.AdminSimplify;

public class AdminListAction extends ActionSupport {

	private List<AdminSimplify> list;

	public List<AdminSimplify> getList() {
		return list;
	}
	/**
	 * 得到当前登陆的管理员
	 * @return
	 */
	public String execute(){

		list=new ArrayList<AdminSimplify>();
		AdminListServler aServler=new AdminListServler(ServletActionContext.getRequest().getSession());
		for (Admin admin : aServler.getList()) {

			AdminSimplify as=new AdminSimplify();
			as.setAddTime(admin.getAddTime());
			as.setAdminName(admin.getAdminName());
			as.setAdminPass(admin.getAdminPass());
			as.setHead(admin.getHead());
			as.setId(admin.getId());
			as.setNickName(admin.getNickName());
			list.add(as);
		}

		return SUCCESS;
	}
}
  

package com.shop.chat;

import java.util.List;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.shop.bean.Admin;

public class AdminMessageAction extends ActionSupport {

	private String to;		//接受用户
	private String result;	//返回消息
	private String content;	//消息内容
	private String nickName;	//昵称
	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	public String getNickName() {
		return nickName;
	}
	public void setContent(String content) {
		this.content = content;
	}
	private List<Message> list;

	public List<Message> getList() {
		return list;
	}

	public void setResult(String result) {
		this.result = result;
	}
	public String getResult() {
		return result;
	}
	public void setTo(String to) {
		this.to = to;
	}


	public String execute(){
		Admin admin=(Admin)ServletActionContext.getRequest().getSession().getAttribute("admin");
		if(admin==null){
			setResult("你还没有登录!");
			return SUCCESS;
		}
		MessageServer msServer=new MessageServer(ServletActionContext.getRequest().getSession(),admin.getId()+"",admin.getNickName());
		list=msServer.getMessage();
		return SUCCESS;
	}

	/**
	 * 发送消息
	 * @return
	 */
	public String send(){
		Admin admin=(Admin)ServletActionContext.getRequest().getSession().getAttribute("admin");
		if(admin==null){
			setResult("没有登录");
			return SUCCESS;
		}

		MessageServer msServer=new MessageServer(ServletActionContext.getRequest().getSession(), admin.getId()+"",admin.getNickName());
		try {
			msServer.send(to, content);
			setResult("发送成功!");
			setNickName(admin.getNickName());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			result=e.getMessage();
		}
		return SUCCESS;
	}


}
  

package com.shop.chat;

/**
 * 信息容器
 * @author Pan
 *
 */

public class Message {

	private String form; // 来自用户
	private String to; // 接受用户
	private String message; // 信息
	private String nickName;	//昵称

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	public String getNickName() {
		return nickName;
	}
	public String getForm() {
		return form;
	}

	public void setForm(String form) {
		this.form = form;
	}

	public String getTo() {
		return to;
	}

	public void setTo(String to) {
		this.to = to;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

}
  

package com.shop.chat;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.shop.bean.User;
import com.sun.org.apache.bcel.internal.generic.NEW;

public class MessageAction extends ActionSupport {

	private String to;			//传送到指定的用户
	private String result;		//返回信息
	private String content;		//内容
	private String nickName;	//昵称
	private List<Message> list;	//消息集合

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	public String getNickName() {
		return nickName;
	}
	public void setResult(String result) {
		this.result = result;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public List<Message> getList() {
		return list;
	}
	public String getResult() {
		return result;
	}
	public void setTo(String to) {
		this.to = to;
	}
	/**
	 * 获取消息
	 */
	public String execute(){

		HttpServletRequest request=ServletActionContext.getRequest();
		User user=(User)request.getSession().getAttribute("user");
		MessageServer msServer=new MessageServer(request.getSession(), user.getId()+"",user.getNickName());
		this.list=msServer.getMessage();

		return SUCCESS;
	}

	/**
	 * 发送消息
	 * @return
	 */
	public String send(){

		HttpServletRequest request=ServletActionContext.getRequest();
		User user=(User)request.getSession().getAttribute("user");
		if(user==null){
			result="你还没有进行登录!";
			return SUCCESS;
		}
		MessageServer mServer=new MessageServer(request.getSession(),user.getId()+"",user.getNickName());
		mServer.getMessage();

		try {
			mServer.send(to, content);

			System.out.println("to:"+to);
			setNickName(user.getNickName());
			setResult("发送成功");
		} catch (Exception e) {
			setResult("发送失败!");
			result=e.getMessage();
		}
		return SUCCESS;
	}
}
  

package com.shop.chat;

import java.util.ArrayList;
import java.util.List;

/**
 * 信息集合 这个对象储存到Application中
 * @author Pan
 *
 */
public class MessageList {

	private List<Message> list=new ArrayList<Message>();

	public MessageList(){

	}

	/**
	 * 添加信息
	 * @param message
	 */
	public void add(Message message){
		list.add(message);
	}

	/**
	 * 寻找信息 通过接受的用户
	 * @param uid
	 * @return
	 */
	public List<Message> getByTo(String uid){
		List<Message> tmp=new ArrayList<Message>();
		System.out.println("list的大小:"+list.size());
		for(Message message:list){
			if(message.getTo().equals(uid)){
				//添加到返回对象
				tmp.add(message);
			}
		}
		//然后移除信息 以免信息重复
		list.removeAll(tmp);
		return tmp;
	}

}
  

package com.shop.chat;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;

public class MessageServer {

	private MessageList mList;
	private ServletContext context;
	private String uid;
	private String nickname;
	public MessageServer(HttpSession session,String uid,String nickname){

		this.context=session.getServletContext();

		Object object=context.getAttribute("mlist");
		if(object==null){
			mList=new MessageList();
			context.setAttribute("mlist", mList);
		}else {
			this.mList=(MessageList)object;
		}
		this.uid=uid;
		this.nickname=nickname;
	}
	/**
	 * 发送数据
	 * @throws Exception
	 */
	public void send(String to,String content) throws Exception{

		if(uid==null){
			throw new Exception("用户名id无效");
		}

		Message message=new Message();
		message.setForm(uid);
		message.setTo(to);
		message.setMessage(content);
		message.setNickName(this.nickname);
		mList.add(message);

	}

	/**
	 * 接受信息
	 * @return
	 */
	public List<Message> getMessage(){
		//返回当前用户的信息
		System.out.println("uid是:"+uid);
		return mList.getByTo(uid);
	}

}
  

package com.shop.chat.admin;

import java.util.ArrayList;
import java.util.List;

import com.shop.bean.Admin;

/**
 * 存放当前已经登陆的管理员列表
 * @author Pan
 *
 */
public class AdminList {

	private List<Admin> list=new ArrayList<Admin>();
	public AdminList(){

	}

	/**
	 * 增加Admin对象
	 * @param admin
	 */
	public void save(Admin admin){
		if(list.indexOf(admin)==-1){
			list.add(admin);
		}
	}

	/**
	 * 得到所有Admin
	 * @return
	 */
	public List<Admin> getList(){
		return list;
	}
}
  

package com.shop.chat.admin;

import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;

import com.shop.bean.Admin;

/**
 * admin列表服务
 * @author Pan
 *
 */
public class AdminListServler {

	private AdminList list;

	public AdminListServler(HttpSession session){
		ServletContext context=session.getServletContext();
		list=(AdminList)context.getAttribute("adminlist");
		if(list==null){
			list=new AdminList();
			context.setAttribute("adminlist", list);
		}
	}
	/**
	 * add an admin to the list
	 * @param admin
	 */
	public void save(Admin admin){
		list.save(admin);
	}

	/**
	 * get all admin object
	 * @return arraylist
	 */
	public List<Admin> getList(){
		return list.getList();
	}
}
  

package com.shop.chat.admin;

import java.sql.Timestamp;

public class AdminSimplify {

	private Integer id;
	private String adminName;
	private String adminPass;
	private String nickName;
	private String head;
	private Timestamp addTime;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getAdminName() {
		return adminName;
	}
	public void setAdminName(String adminName) {
		this.adminName = adminName;
	}
	public String getAdminPass() {
		return adminPass;
	}
	public void setAdminPass(String adminPass) {
		this.adminPass = adminPass;
	}
	public String getNickName() {
		return nickName;
	}
	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	public String getHead() {
		return head;
	}
	public void setHead(String head) {
		this.head = head;
	}
	public Timestamp getAddTime() {
		return addTime;
	}
	public void setAddTime(Timestamp addTime) {
		this.addTime = addTime;
	}

}
  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 网站用户在线和客服聊天 的相关文章

  • Oracle与OpenJDK之间的区别

    简介 在本文中 xff0c 我们将探讨Oracle Java Development Kit和OpenJDK之间的差异并进行比较 Oracle JDK Oracle JDK由Oracle公司开发 xff0c 该公司是Sun许可证 xff0c
  • Maven 3.6.1版本

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 下载和配置 下载Maven 解压到文件目录下 mac配置maven环境变量 conf settings xml 仓库路径默认目录地址 xff0c 可修改 lt localR
  • 如何解决“ add-apt-repository命令未找到”的错误,在Ubuntu,Debian,Mint,Kali中

    deb or apt based distributions like Debian Ubuntu Mint and Kali uses apt package management system These distributions p
  • 浅谈运营商线路-----TDM、SDH、MSTP,OTN

    我单位的运营商专线有SDH和MSTP两种 xff0c 那么它们有什么区别呢 xff0c 这个isp的东西 xff0c 相信很多同学一脸懵 xff0c 因为你工作的层级问题 xff0c 很多人都是二层以上的 xff0c 所以不了解也是正常的
  • autodesk CAD2020许可检出超时

    笔记本电脑系统为windows7 xff0c 系统休眠后没有正常恢复系统 xff0c 之后使用cad2020提示 许可检出超时 xff0c 开始通过重新安装cad软件可以正常使用 xff0c 但休眠后cad还是会出现同样的提示 查询CAD官
  • Presto SQl中使用date_format()和date_parse()遇到的问题

    昨天在Presto中查数据 查出来数据不对 后来发现是我使用date parse 函数有问题 我需要查2018年12月31号到2019年1月6号之间的数据 我使用的时间过滤方式是 and behavior datetime gt 61 da
  • vue点击实现 路由的跳转

    点击按钮实现路由的跳转 lt div 64 click 61 34 gotoMenu 34 gt 按钮 lt div gt 实现跳转 methods gotoMenu 跳转到上一次浏览的页面 this router go 1 this ro
  • 分享一下我在东方时尚学车的经历

    楼主是4月26日报的名 xff0c 7月22日拿的本 xff0c 不算快的 xff0c 不过也不算慢的 和大多数简子们一样 xff0c 楼主也是个苦比的白领一族 xff0c 白天上班 xff0c 大多数都是晚上去学车 xff0c 每一次请个
  • Linux Kernel Development有关内存管理

    1 Pages Page的概念来源为处理器Processor的部件MMU Memory Management Unit xff0c MMU通过设置好的页表 通过设置CR3寄存器 xff0c 指向页目录所在的物理内存 对内存进行管理 xff0
  • 控件权限管理思路

    1 编写判断用户角色相关的类及方法 protected bool ShowButtonBasedOnRole string RoleOfInterest return User IsInRole RoleOfInterest 2 通过调用相
  • 华为交换机LACP模式链路聚合配置

    交换机A和交换机B之间通过3条GE以太网连接 xff0c 活动链路为2 xff0c 配置如下 xff1a SwitchA配置 lt HUAWEI gt system view HUAWEI sysname SwitchA SwitchA i
  • 检查HTTP 的 Digest 认证代码示例-JSP

    检查HTTP 的 Digest 认证 since http1 1 代码如下所示 xff1a 此代码还不完善 RFC2617算法未实现 lt 64 page pageEncoding 61 34 UTF 8 34 contentType 61
  • 每天一个linux命令(4):mkdir命令

    linux mkdir 命令用来 创建指定的 名称的 目录 xff0c 要求创建目录的用户在当前目录中具有写权限 xff0c 并且指定的目录名不能是当前目录中已有的目录 1 xff0e 命令格式 xff1a mkdir 选项 目录 2 xf
  • 历史上消失的十天--儒略日(Julian Days)的来历

    儒略日是由法国学者 Joseph Justus Scaliger xff08 1540 1609 xff09 发明的 xff0c 名称可能是取自 Scaliger 的父亲 xff0c 意大利学者Julius Caesar Scaliger
  • “ -bash:sudo:未找到命令”对于Linux,Debian,CentOS的错误和解决方案

    sudo command is used to execute command as another user This is generally used to run command as root In some cases we c
  • 球机和云台的差别 以及他们的组成

    说的 球机 和 云台 的差别那不得不介绍球机和云台的概念了 xff0c 球机全称为球型 摄像机 xff0c 是现代电视监控发展的代表 xff0c 她集成彩色一体化摄像机 云台 解码器 防护罩等多功能与一体 xff0c 安装方便 使用简单但功
  • [Shell学习笔记] 命令行下的高级网络工具cURL命令

    原文 xff1a http www 1987 name 365 html Linux curl命令是一个利用URL规则在命令行下工作的文件传输工具 它支持文件的上传和下载 xff0c 所以是综合传输工具 xff0c 但按传统 xff0c 习
  • 74系列的型号

    74系列TTL数字逻辑集成电路系国际上通用的标准电路 其品种共分为六大类即 74xx 标准 74LSxx 低功耗肖特基 74Sxx 肖特基 74ALSxx 先进低功耗肖特基 74ASxx 先进肖特基 74Fxx 高速 只要序列号相同 xff
  • 【C#】使用fo-dicom完成BMP,JPG,PNG图片转换为DICOM文件

    最近研究了一下DICOM和BMP文件转换的问题 xff0c 也是很头大 度娘了很久 xff0c 也在CSDN等论坛看到一些断断续续的文件 xff0c 最主要的是代码只是片断 xff0c 不是完整的实现 头大了 首先 xff0c 了解一下BM
  • Atomix getting start 浓浓的机翻

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 概观 Atomix 2 1是用于构建容错分布式系统的全功能框架 Atomix将ZooKeeper的一致性与Hazelcast的可用性和性能相结合 xff0c 使用一组定制通

随机推荐

  • Formik与antd-mobile的移动端的表单实践(下)

    大家好 xff0c 工作闲暇之余又来续写一下Formik这个库的文章了 xff0c 这次文章主要内容为如下 xff1a 更多表单组件的封装示例 单选 多选按钮选择器时间选择器文本输入框提交按钮Formik的表单验证Formik的表单提交处理
  • nginx与tomcat组合使用时获取客户端真实IP

    为什么80 的码农都做不了架构师 xff1f gt gt gt Nginx 43 Tomcat做反向代理在Tomcat中无法获取用户的真实IP解决步骤 xff1a 1 在Nginx配置文件中配置传递到Tomcat的IP变量名 xff1a 一
  • 记一次创建云硬盘失败的解决过程

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 一 背景 登录dashboard xff0c 点击创建云硬盘失败 xff0c 而且是点击完就直接报error错误 二 解决经过 思路一 xff1a 新上传的image镜像
  • linux samba 配置

    1 所需要软件包 samba common软件包中提供了samba服务器和客户中都必须使用的公共文件 samba软件包中包括了samba服务器程序的所有文件 samba client软件包中提供了Samabe客户机器的所有文件 system
  • tightvnc 远程开机_如何在Linux中安装和访问TightVNC远程桌面?

    tightvnc 远程开机 TightVNC is a very handy remote desktop application which is based on VNC protocol TightVNC is mostly used
  • linux grub命令行,引导工具GRUB详解

    导读 引导程序是驻留在硬盘第一个扇区 MBR 主引导记录 的程序 GRUB是一个功能强大的多系统引导程序 xff0c 专门处理Linux与其它操作系统共存的问题 下面就由我介绍一下grub conf文件里的具体内容及其含义 使用一下命令可以
  • Formik官方应用案例解析(三)使用react-select

    react select简介 React Select是github上一个极其火的控件库 xff0c 星数达到13004 xff0c 它是React开发中几乎是你必需打交道的一个内容 React Select的基本功能实现的是一个表单中的常
  • Juniper MPLS Static LSP

    MPLS Static LSP 1 配置接口去接收和处理MPLS帧 user 64 R1 set interface ge 1 0 0 unit 0 family inet family mpls 2 指定哪个接口运行MPLS user 6
  • 201803考试批次2C 程序设计语言,重庆大学201803批次2可视化程序设计(VB)D卷答案...

    201803考试批次2可视化程序设计 VB D卷 5 O0 R K G l可视化程序设计 VB l K 3 Z t 一 单项选择题 共 10 题 0 20 分 c c N G1 F4 D6 39 64 1 下列程序段的执行结果为 Dim x
  • VNC注册码

    5D7L8 ZQXSA 2L5D4 4UFB4 PWDLA 转载于 https blog 51cto com ciscolinux 1320541
  • matlab中矩阵可视化,matlab-如何可视化显示颜色和值的矩阵?

    您可以使用内置功能 39 X Y Z TickLabelRotation 39 和 39 X Y Z TickLabelRotation 39 并调整图形对象的许多参数 xff0c 轻松地自己创建此类绘图 这是一个例子 xff1a mat
  • Formik与antd-mobile的表单实践(上)

    概览 本文主要用于记录该次使用Formik时用到的相关接口 xff0c 而侧重点不在antd mobile xff0c 对antd mobile会贴出对应组件API 文章需要基础知识点 xff1a React基本知识ES6基本知识 文章实践
  • AT&T CORD架构解读

    这一两年 xff0c 我们时常听到CORD项目 xff08 Central Office Re Architected as a Data Center xff09 AT amp T希望通过CORD项目将运营商网络中的传统端局 xff08
  • 发送端口25,465,587端口疑问解答

    25端口 xff08 SMTP xff09 xff1a 25端口为SMTP xff08 Simple Mail Transfer Protocol xff0c 简单邮件传输协议 xff09 服务所开放的 xff0c 是用于发送邮件 如今绝大
  • brctl 命令详解

    安装网桥管理工具包 xff1a bridge utile 96 96 96 yum install bridge utils y 96 96 96 96 96 96 使用brctl命令创建网桥br1 96 96 96 brctl addbr
  • 缓存缓存CSS的策略

    浏览器缓存CSS将带来主要的性能提升 您确保服务器设置为发送标头 xff0c 这些标头告诉浏览器在给定的时间内挂接到CSS文件 最好的做法是 xff0c 即使不是大多数站点 xff0c 许多站点已经在这样做 与浏览器缓存紧密结合的是缓存清除
  • John the Ripper 安装用使用

    试着在ubuntu下安装了John the Ripper最新版本 xff11 7 9 xff0c 非常不给面子 xff0c 不成功 xff0c 总是报 34 No password hashes loaded 34 的错误 最终参照这篇文章
  • Vue父组件接收不到子组件$emit事件的原因分析

    通常有两种情况 xff1a 事件名称不全是小写 事件名称要求全小写 不是父子关系 这里的父子关系是严格的父子关系 xff0c 祖孙关系也不行 只能一层一层触发 xff0c 这在写树形组件时 xff0c 很容易掉坑里
  • NUMA的关闭方法【转】

    Centos 6 在 etc grub conf 在kernel 添加numa 61 off 就行了 一 检查OS是否开启NUMA numactl hardware available 1 nodes 0 如果是2或多个nodes就说明nu
  • java 网站用户在线和客服聊天

    注 xff1a 本文来源于 java 网站用户在线和客服聊天 这是应用到项目中的一个例子 实现原理是将信息存储到Application域里面 然后使用Struts2 Action 用json格式的数据进行前后台交互 截图 xff1a 前台用