写这个玩意儿就是想练练手, 用户需要登陆才能在线聊天,不要依赖数据库, 不需要数据库的操作, 所有的数据都是保存在内存中, 如果服务器一旦重启,数据就没有了;

  登录界面:

  

  聊天界面:

  

  左侧是在线的用户列表, 右侧是聊天的内容, 内容的格式为 “作者 : 内容”;

  点击button可以发布聊天信息;

  

  使用的是spring搭建的框架,基于tomcat的服务器;

  web.xml的配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
</welcome-file-list> <servlet>
<servlet-name>test</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.nono.Filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter> <filter>
<filter-name>SecurityServlet</filter-name>
<filter-class>com.nono.SecurityServlet</filter-class>
</filter>
<filter-mapping>
<filter-name>SecurityServlet</filter-name>
<url-pattern>*.htm</url-pattern>
</filter-mapping> <!--
使用Spring中的过滤器解决在请求和应答中的中文乱码问题
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
强制转换编码(request和response均适用)
<param-name>ForceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
--> <context-param>
<param-name>
contextConfigLocation
</param-name>
<param-value>
/WEB-INF/test-servlet.xml
</param-value>
</context-param>
</web-app>

  conteConfigLocation的配置为:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <context:annotation-config> </context:annotation-config>
<context:component-scan base-package="com.nono" > </context:component-scan> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>

  

  整个项目的结构为一个主路由, 四个po层,  两个过滤器:

  

  界面的用户列表和用户内容列表用了ajax刷新, 感觉不错的说:

<!--
修改pageEncoding为 utf-8
-->
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>login</title>
<meta charset="utf-8">
<link href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/jquery/1.9.0/jquery.js"></script>
</head>
<style>
html,body,.bg{
height:100%;
}
.bg{
background:url(imgs/bg.jpeg);
}
</style>
<body>
<div class="container-fuild bg">
<div class="row">
<div class="col-sm-4">
<div class="page-header">
<h2>
list
</h2>
<ol id="list">
<li>name—</li>
<li>name—</li>
<li>name—</li>
<li>name—</li>
</ol>
</div>
</div>
<div class="col-sm-8">
<h2>
content
</h2>
<div id="con" class="page-header">
<p>
<b>haha:</b>
<big>
say someting
</big>
</p>
<p>
<b>haha:</b>
<big>
say someting
</big>
</p>
</div>
<form>
<div class="form-group">
<label for="text">enter text</label>
<input type="text" id="answer" class="form-control" id="text" placeholder="text">
</div>
<button type="button" id="sb" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
<script>
$("#sb").click(function() {
$.post("chat.htm", "content="+ $("#answer").val(), function(data) {
console.log(data);
});
}); function Get(url , el, fn) {
this.post = function() {
$.post(url, function(data) {
data = JSON.parse(data);
var html = "";
$.each(data,function(i, e) {
html += fn(i,e);
});
$(el).html( html );
});
};
}; (function() { var list = new Get("getList.htm", "#list", function(i, e) {
return "<li>" + e.name + "</li>";
}); var content = new Get("getContent.htm", "#con", function(i, e) {
return "<p><b>"+ e.name +" : </b><big>"+ e.content +"</big></p>";
}); setInterval(function() {
list.post();
content.post();
},1000); })();
</script>
</body>
</html>

  权限控制的话我们可以用到fileter:

package com.nono;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import com.nono.po.User; public class SecurityServlet extends HttpServlet implements Filter {
private static final long serialVersionUID = 1L; public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)arg0;
HttpServletResponse response =(HttpServletResponse) arg1;
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
String url=request.getRequestURI();
//如果用户信息不是空的, 或者要访问的是登陆的界面(get,post的方式包含了login字符串);
if( user!=null || url.indexOf("login")>-1 ) {
arg2.doFilter(arg0, arg1);
return;
}else{
//余下的全跳到登陆界面
response.sendRedirect(request.getContextPath() + "/login.htm");
return;
}
}
public void init(FilterConfig arg0) throws ServletException {
} }

  路由控制和服务放到了一起, 因为权限控制使用过滤器处理, 所以在路由里面我们就不用关心用户的消息, 只要处理业务逻辑就好了:

package com.nono.Controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector; import javax.jms.Session;
import javax.print.DocFlavor.STRING;
import javax.print.attribute.HashAttributeSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import net.sf.json.JSONArray; import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import com.nono.po.Content;
import com.nono.po.Contents;
import com.nono.po.User;
import com.nono.po.Users; @Controller
public class MainController {
//用户和用户组;
@Autowired
Users users; @Autowired
Contents contents; @RequestMapping(value="login", method=RequestMethod.GET)
public String login (HttpServletRequest request) {
return "login";
} @RequestMapping(value="login", method=RequestMethod.POST)
public String loginPOST ( HttpServletRequest request, HttpServletResponse response ) { String string = "login";
String name = (String) request.getParameter("name");
Boolean flag = true;
//如果名字不是空的话;
if( !name.equals("") ) {
Vector vector = users.getList();
for(int i=0; i< vector.size(); i++) {
User user = (User) vector.elementAt(i);
if( user.getName().equals( name ) ) {
flag = false;
};
};
}; //用户名不存在
if( flag ) {
User user = new User();
user.setName( name );
HttpSession session = request.getSession(true);
//设置Session的过期时间为10分钟
session.setMaxInactiveInterval(600);
//设置seesion中的用户信息;
session.setAttribute("user", user);
//添加用户;
users.addUser( user ); //加入的提示;
Content content = new Content();
content.setName( name );
content.setContent( "enter the chat room!" );
contents.addContent( content ); string = "chat";
return string;
}else{
//用户名已经存在
request.setAttribute("info", "用户名已经存在1");
string = "login";
return string;
}
} @RequestMapping(value="chat", method=RequestMethod.GET)
public String main (HttpServletRequest request) {
String string = "chat";
return string;
} @RequestMapping(value="chat", method=RequestMethod.POST)
@ResponseBody
public String chat(HttpServletRequest request) {
String string = (String) request.getParameter("content");
HttpSession session = request.getSession();
//设置seesion中的用户信息;
User user = (User) session.getAttribute("user");
String name = user.getName();
Content content = new Content();
content.setName( name );
content.setContent( string );
contents.addContent( content );
return "true";
} @RequestMapping(value="getList", method=RequestMethod.POST, produces = "text/html;charset=UTF-8")
@ResponseBody
public String getList( HttpServletRequest request) {
return JSONArray.fromObject( users.getList() ).toString();
} @RequestMapping(value="getContent", method=RequestMethod.POST, produces = "text/html;charset=UTF-8")
@ResponseBody
public String getArrayList() {
ArrayList list = (ArrayList) contents.getContents();
ArrayList result = new ArrayList();
for( int i= 0; i< list.size(); i++ ) {
HashMap<String,String> hashMap = new HashMap();
hashMap.put("name", ((Content)list.get(i)).getName());
hashMap.put("content", ((Content)list.get(i)).getContent());
result.add( hashMap );
};
return JSONArray.fromObject( result ).toString();
} }

  有哪位大神告诉我为什么中文各种乱码, 在界面中的utf-8也设置, @ResponseBody的也设置了, 还是乱码, encodeURIComponent过的也是乱码, 坑爹啊;

  

作者: NONO
出处:http://www.cnblogs.com/diligenceday/

QQ:287101329

javaweb写的在线聊天应用的更多相关文章

  1. 三分钟搭建websocket实时在线聊天,项目经理也不敢这么写

    我们先看一下下面这张图: 可以看到这是一个简易的聊天室,两个窗口的消息是实时发送与接收的,这个主要就是用我们今天要讲的websocket实现的. websocket是什么? websocket是一种网 ...

  2. 在线聊天室的实现(1)--websocket协议和javascript版的api

    前言: 大家刚学socket编程的时候, 往往以聊天室作为学习DEMO, 实现简单且上手容易. 该Demo被不同语言实现和演绎, 网上相关资料亦不胜枚举. 以至于很多技术书籍在讲解网络相关的编程时, ...

  3. 百度前端面试题-类似slack的在线聊天室

    别人国庆出去玩,我在家写代码的感觉也是很不错哒. 首先介绍一下技术架构吧! 使用了js框架:FFF,zepto,jquery,md5.min.js 前端框架:Bootstrap 后端:野狗,部分PHP ...

  4. java Socket实现简单在线聊天(二)

    接<java Socket实现简单在线聊天(一)>,在单客户端连接的基础上,这里第二步需要实现多客户端的连接,也就需要使用到线程.每当有一个新的客户端连接上来,服务端便需要新启动一个线程进 ...

  5. Python进阶开发之网络编程,socket实现在线聊天机器人

    系列文章 √第一章 元类编程,已完成 ; √第二章 网络编程,已完成 ; 本文目录 什么是socket?创建socket客户端创建socket服务端socket工作流程图解socket公共函数汇总实战 ...

  6. Spring Websocket实现简易在线聊天功能

    针对Spring Websocket的实现,我参照了其他博主的文章https://www.cnblogs.com/leechenxiang/p/5306372.html 下面直接给出实现: 一.引入相 ...

  7. AngularJS+Node.js+socket.io 开发在线聊天室

    所有文章搬运自我的个人主页:sheilasun.me 不得不说,上手AngularJS比我想象得难多了,把官网提供的PhoneCat例子看完,又跑到慕课网把大漠穷秋的AngularJS实战系列看了一遍 ...

  8. Go语言实践_实现一(服务器端)对多(客户端)在线聊天室

    一.目的 运用Go语言中的goroutine和通道实现一个简单的一个服务器端对多个客户端的在线聊天 软件环境:Goland,Go1.9 代码仓库链接 二.设计思路 与一对一的设计思路类似,就是加了个线 ...

  9. SignalR实现在线聊天室功能

    一.在线聊天室 1.新建解决方案 SignalROnlineChatDemo 2.新建MVC项目 SignalROnlineChatDemo.Web (无身份验证) 3.安装SignalR PM> ...

随机推荐

  1. openjudge2989糖果[DP 01背包可行性]

    openjudge2989糖果 总时间限制:  1000ms 内存限制:  65536kB 描述 由于在维护世界和平的事务中做出巨大贡献,Dzx被赠予糖果公司2010年5月23日当天无限量糖果免费优惠 ...

  2. ural 1208 Legendary Teams Contest

    题意描述:给定K支队伍,每队三个队员,不同队伍之间队员可能部分重复,输出这些队员同时能够组成多少完整的队伍: DFS,利用DFS深度优先搜索,如果该队所有队员都没有被访问过,那么将该队计入结果,再去选 ...

  3. vijos1334 NASA的食物计划(二维费用的背包问题)

    背景 NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安 全技术问题一直大伤脑筋,因此在各方压力下终止了航天 飞机的历史,但是此类事情会不会在以后发生,谁也无法 保证,在遇到这类航天问题时,解决方 ...

  4. Tree

    //Header.h #ifndef _HEAD_ #define _HEAD_ #include <queue> #include <iostream> using name ...

  5. HTML 学习笔记 CSS(表格)

    CSS 表格属性可以帮助您极大的改善表格的外观 表格边框 如需在CSS中设置表格的边框 请使用border属性. 在下面的例子中table th 以及td设置了蓝色边框. table, th, td ...

  6. HTML DOM Document 对象

    HTML DOM Document 对象 HTML DOM 节点 在 HTML DOM (Document Object Model) 中 , 每一个元素都是 节点: 文档是一个文档. 所有的HTML ...

  7. Html5 Egret游戏开发 成语大挑战(二)干净的eui项目和资源准备

    现在我们使用egret来起步开发一个名叫<成语大挑战>的小游戏,关于egret的开发环境就不在这里啰嗦了,直接去官方下载安装就可,egret是我见过开发环境部署最简单的解决方案,这个系列教 ...

  8. Visual Studio 2012 cannot identify IHttpActionResult

    使用ASP.NET Web API构造基于restful风格web services,IHttpActionResult是一个很好的http结果返回接口. 然而发现在vs2012开发环境中,Syste ...

  9. C#TCP通讯框架

    开源的C#TCP通讯框架 原来收费的TCP通讯框架开源了,这是一款国外的开源TCP通信框架,使用了一段时间,感觉不错,介绍给大家 框架名称是networkcomms 作者开发了5年多,目前已经停止开发 ...

  10. Linux 网络编程详解七(并发僵尸进程处理)

    在上一篇程序框架中,解决了子进程退出,父进程继续存在的功能,但是多条客户端连接如果同一时间并行退出,导致服务器端多个子进程同一时间全部退出,而SIGCHLD是不可靠信号,同时来多条信号可能无法处理,导 ...