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

  登录界面:

  

  聊天界面:

  

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

  点击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. 第18章 图元文件_18.2 增强型图元文件(emf)(1)

    18.2 增强型图元文件(emf) 18.2.1 创建并显示增强型图元文件的步骤 (1)创建:hdcEMF = CreateEnhMetaFile(hdcRef,szFilename,lpRect,l ...

  2. XBOX ONE游戏开发之登陆服务器(一)

    XBOX ONE游戏开发之登陆服务器(一) XBOX LIVE是微软自已的认证服务器, 当我们开发游戏时,如果是联网游戏,需要自已架设单点登陆(SSO)服务器 这个需要微软提供Relying Part ...

  3. u3d_Shader_effects笔记2 自定义surfaceDiffuseLight

    1.前面的心情 今晚7点半睡着后,9点半左右被吵醒.醒来后非常失落,感觉人生到底在追求什么,我又在追求什么.昨晚梦到妈妈了.最近不时会想到爷爷的去世.人世的险恶,良心的缺失.不过一切总要向前看,至少我 ...

  4. 当手机被PS掉,人们看到的是手中的灵魂

    Eric Pickersgill是一名摄影师,最近喜欢拍摄并记录人们使用智能手机的情景,不过不同的是,在最终作品中会将手机从人们手中PS掉,一刹那会进入一个奇怪的世界.黑白照片也极具冲击力. 每个人神 ...

  5. SpringMVC讲解

    2.1.Spring Web MVC是什么 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职 ...

  6. poj 3264

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 44594   Accepted: 20931 ...

  7. webclient 比浏览器加载页面慢的一个问题

    测试中发现webclient 比浏览器加载页面慢的一个问题:原因WebClient 支持 gzip, deflate,但是未设置 解决方案: class WebClientEx : WebClient ...

  8. 个人PHP开发环境的选择与搭建

    入职一个多月,重新调整了一下自己电脑的开发环境,现在写出来,算是作为自己的笔记. 如果你是该文章的读者,请忍受文章内的所有小章节都没有具体的步骤. 因为平时还要打游戏(划掉),所以电脑系统一直是Win ...

  9. log4j.properties 详解与配置步骤(转)

    找的文章,供参考使用 转自 log4j.properties 详解与配置步骤 一.log4j.properties 的使用详解 1.输出级别的种类 ERROR.WARN.INFO.DEBUGERROR ...

  10. oracle小知识总结

    1,表列的五种约束 not null, unique,primary key, foreign key, check 2,权限分配 grant 权限 on 表 to 用户 3,表和视图的区别 视图是一 ...