基於servlet和ajax的聊天室
(手賤點了更新發布時間,發布時間變成6-9。。。)
2017-5-20,在這個奇特的日子,我不再滿足於在本地測試javaweb,於是在上騰訊雲買了第一個雲伺服器,由於是學生認證,所以一個月只要10塊錢,還是要搶的,每天早上9點開搶(騰訊雲的學生優惠活動好像取消了,所以我又選擇了阿里雲)打開後,發現其實是一個雲主機,就是遠程主機,只不過他可以給你一個公網ID,就是在瀏覽器輸入公網ID的話,全國所有人都可以訪問你的項目
關於怎麼把自己的javaweb項目放到雲主機,有一個教程http://www.cnblogs.com/diyunfei/p/6826557.html,前提是得先在雲主機下載配置jkd,tomcat
安裝eclipse後先安裝servers,在help中的安裝軟體,輸入http://download.eclipse.org/releases/kepler,選擇Web,XML, java EE and OSGi Enterprise Development
配置jdk
新建 JAVA_HOME 變數 。
變數值填寫jdk的安裝目錄
尋找 Path 變數
在變數值最後輸入 %JAVA_HOME%in;%JAVA_HOME%jrein;
(注意原來Path的變數值末尾有沒有;號,如果沒有,先輸入;號再輸入上面的代碼)
新建 CLASSPATH 變數
.;%JAVA_HOME%lib;%JAVA_HOME%lib ools.jar(注意最前面有一點)
檢驗是否配置成功 運行cmd 輸入 java -version (java 和 -version 之間有空格)
若如圖所示 顯示版本信息 則說明安裝和配置成功。
配置tomcat
新建CATALINA_HOME,變數值是tomcat的安裝路徑
找到PATH,在最後增加tomcat的bin文件的絕對路徑(我的就是F:eclipseapache-tomcat-7.0.77in)
配置後可以在瀏覽器輸入localhost:8080,試試看可以可以訪問tomcat的主頁,如果可以即為配置成功
雲主機全部準備好了之後,可以把在本機的eclipse中的maven項目導出成一個war包,複製這個war包到雲主機,放到tomcat的webapp的目錄下,打開tomcat/bin里的start.bat,然後就可以在別的電腦通過「公網ID:埠號/項目名/」的方式訪問該項目
----------------------------------------------------------------------------------------------------------------------------------
下面開始說我這個項目,是跟我室友合作的,前端頁面是他做的,這個是一個多人即時聊天室,在此之前沒有接觸過怎麼實現即時聊天,走了很多彎路,不過幸好可以說是摸出點門道。
一、實現效果如下:
1、先進入登錄界面,輸入呢稱和選擇頭像後進入
2、進入後的界面是這樣的:
3、然後就可以輸入聊天內容了
二、主要邏輯代碼
因為我現在只會後端,就不把前端的代碼貼出來了,主要邏輯是建立在servlet和ajax通信之上
1、我使用maven來構建這個項目,不過我這裡並沒有用maven來導入包,因為就幾個包,我就手動導入項目結構如下
2、Control類用來接收用戶名,頭像id,聊天內容,然後生成一個系統當前時間,把這4個當成參數傳給Model,這裡先說一下為什麼要生成一個系統當前時間,這就說到我遇到的另一個問題了,本來我們是商量說讓前台把用戶名,頭像id,聊天內容,用戶當前時間也傳過來,但是發現效果並不好,因為如果涉及到多人同時聊天,各個客戶端的當前時間不一定會一樣,會造成一些請求得不到正確的響應,然後就想了個辦法,客戶端在發送聊天記錄這條請求時,只發送用戶名,頭像id,聊天內容,然後由伺服器生成時間作為響應返回,然後把4個屬性傳給Model
1 public class Control extends HttpServlet {
2
3 @Override
4 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
5
6 doGet(req, resp);
7 }
8
9 @Override
10 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
11 throws ServletException, IOException {
12
13 // 接受聊天記錄不發送東西:1
14 req.setCharacterEncoding("utf-8");
15
16 String username = req.getParameter("username");// 用戶名
17 String content = req.getParameter("content");// 內容
18 String pic = req.getParameter("picture");
19 SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");// 設置日期格式
20
21 String time = df.format(new Date);
22
23 String callbackName = req.getParameter("jsoncallback");// 時間
24 // -------------------------------------------------------------------------
25
26 try {
27 new Model;
28 Model.write(username, content, time, pic);
29 } catch (ClassNotFoundException e) {
30 e.printStackTrace;
31 }
32 String success = "success";
33 String result = "{"success":"" + success + "","time":"" + time + ""}";
34
35 String renderStr = callbackName + "(" + result + ")";
36 resp.setContentType("text/plain;charset=UTF-8");
37 resp.getWriter.write(renderStr);
38 }
39
40 }
這裡的success只是為了給前台做判斷。。裡面的time也是前台用來給聊天內容打時間標籤用的,json數據是動態拼接的,然後以callbackname作為函數名,直接返回一個字元串
2、Model類是做數據處理的,就是把4個屬性存到keyvaluepair對象中,然後在把對象存到Arraylist中,Model里有3個方法:
(1)fileinit方法是初始化一個流,打開txt文件的開口,(其實這裡我本來是想用mybatis,但是時間倉促我就說先存在txt里湊合吧,以後找時間改一下)
(2)write是把4個屬性追加到文件尾,這裡遇到的問題是,寫到文件里的中文變成了亂碼,所以我就把他處理了一下URLDecoder.decode(username, "UTF-8");
(3)getContent方法是用來提取數據用的,用的key就是時間
1 public class Model { 3、GetCurrentTime這個類就是用來返回當前時間的 public class GetCurrentTime extends HttpServlet { @Override @Override String callbackName = req.getParameter("jsoncallback"); } }
4、SendServlet這個類是用來提取聊天數據的,前台在GetCurrentTime那個servlet中接收到我的系統時間後,把這個系統時間當成一個參數然後發送一個請求到SendServlet,然後我就去調用Model的getcontent,返回一個keyvaluepair對象, 利用這個對象調出所有數據,可以看到json數據都是動態拼接的方法做成的,甚是拙劣 1 public class SendServlet extends HttpServlet { 5、keyvaluepair對象時用來保存那4個屬性的bean,就一個構造函數和4個get方法 public class KeyValuePair { public static String Key; public KeyValuePair(String k, String n,String c,String p) { public static String getName(String k){ public static void main(String[] args) { } 三、還存在的問題 1、當用戶輸入很快的時候有時候會丟失聊天數據 2、裡面沒有把聊天數據保存到資料庫,而是單純保存在Arraylist中和txt中,一旦宕機重啟,後果很嚴重。。。關於mysql資料庫,以前用的都是解壓版,在windowserver2012好像不能用,反正我試了好多次都不行,到最後迫不得已下載了安裝版,才把mysql搞定。(雖然我裡面沒用到資料庫。。。==)安裝版資料庫教程 3、servlet怎麼跟ajax異域通訊,那時候還沒有學spring,所以糾結了很久,查了資料到最後發現是通過一個很不「優雅」的方式進行通信的,就是強行拼接一個json數據類型,不知道還有沒有更好的方法
2 public static BasicDataSource ds = null;
3
4 public final static String JDBC_DRIVER = "com.mysql.jdbc.Driver";
5 public final static String USER_NAME = "root";
6 public final static String PASSWORD = "123456";
7 public final static String DB_URL = "jdbc:mysql://localhost/shen_db?useUnicode=true&characterEncoding=utf-8&useSSL=false";
8
9 public static FileWriter writer = null;
10 public static OutputStreamWriter osw = null;
11 public static FileOutputStream fos = null;
12 static List
13
14 public Model {
15 fileInit;
16 }
17
18 // public static void dbcpInit {
19 // ds = new BasicDataSource;
20 // ds.setUrl(DB_URL);
21 // ds.setDriverClassName(JDBC_DRIVER);
22 // ds.setUsername(USER_NAME);
23 // ds.setPassword(PASSWORD);
24 //
25 // }
26 public static void fileInit {
27 String fileName = "C:\a.txt";
28 try {
29 fos = new FileOutputStream(fileName, true);
30 } catch (FileNotFoundException e1) {
31 e1.printStackTrace;
32 }
33 try {
34 osw = new OutputStreamWriter(fos, "UTF-8");
35 } catch (UnsupportedEncodingException e1) {
36 e1.printStackTrace;
37 }
38 }
39
40 public static void write(String username, String content, String time, String pic)
41 throws ClassNotFoundException {
42 // Connection connection = null;
43 // PreparedStatement preparedStatement = null;
44 String x = null;
45 String y = null;
46 try {
47 x = URLDecoder.decode(username, "UTF-8");
48 y = URLDecoder.decode(content, "UTF-8");
49 } catch (UnsupportedEncodingException e1) {
50 e1.printStackTrace;
51 }
52 String z = time;
53 String p = pic;
54 System.out.println("發送東西來的內容:" + y); 57
58 list.add(new KeyValuePair(z, x, y, p));
59 try {
60 osw.write(KeyValuePair.getKey);
61 osw.write("---");
62 osw.write(KeyValuePair.getPic(z));
63 osw.write("---");
64 osw.write(KeyValuePair.getName(z));
65 osw.write("---");
66 osw.write(KeyValuePair.getContent(z));
67 osw.write("
");
68 } catch (IOException e) {
69 e.printStackTrace;
70 } finally {
71 try {
72 if (osw != null) {
73 osw.close;
74 }
75 } catch (IOException e) {
76 e.printStackTrace;
77 }
78 }
79
80 // try {
81 // connection = ds.getConnection;
82 // preparedStatement = connection.prepareStatement("insert into Chatlog
83 // (time,logs) values (?,?)");
84 // preparedStatement.setString(1, currentTime);
85 // preparedStatement.setString(2, x);
86 // } catch (SQLException e) {
87 //
88 // e.printStackTrace;
89 // }
90
91 }
92
93 public static KeyValuePair getContent(String time) {
94
95 String time1 = time;
96 KeyValuePair kvp = null;
97 if (list.isEmpty) {
98 } else {
99 for (KeyValuePair ss : list) {
100 if (time1.equals(ss.getKey)) {
101 kvp = ss;
102 } else {
103 kvp = null;
104 }
105 }
106 }
107 return kvp;
108 }
109
110 public static void main(String[] args) {
111
112 new Model;
113 }
114
115 }
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get current time");
String time = null;
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
time=df.format(new Date);
String result=null;
result="{"time":""+time+""}";
String renderStr = callbackName + "(" + result + ")";
resp.setContentType("text/plain;charset=UTF-8");
resp.getWriter.write(renderStr);
2
3 @Override
4 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
5 doPost(req, resp);
6 }
7
8 @Override
9 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
10
11
12 String time = req.getParameter("time");
13 System.out.println("時間"+time);
14 KeyValuePair kvp = null;
15 String result = "{"content":"" + null + "","time":"" + null + "","name":"" + null
16 + "","picture":"" + null + ""}";
17 String callbackName4 = req.getParameter("jsoncallback");
18
19 try {
20 kvp = Model.getContent(time);
21 System.out.println(kvp);
22 if (kvp != null) {
23 result = "{"content":"" + kvp.getContent(time) + "","time":"" + kvp.getKey + "","name":""
24 + kvp.getName(time) + "","picture":""+kvp.getPic(time) +""}";
25 }
26 kvp = null;
27 String renderStr = callbackName4 + "(" + result + ")";
28 resp.setContentType("text/plain;charset=UTF-8");
29 resp.getWriter.write(renderStr);
30
31 } catch (IOException e) {
32 e.printStackTrace;
33 }
34 }
35
36 }
public static String Name;
public static String Content;
public static String Pic;
Key = k;
Name = n;
Content =c;
Pic=p;
}
return Name;
}
public static String getPic(String k){
return Pic;
}
public static String getKey{
return Key;
}
public static String getContent(String k){
return Content;
}
}
4、不能查看聊天記錄
5、在學習sockets中。。
※vue-router路由參數刷新消失的問題
※沒有main方法真的不能執行代碼了嗎?
※網頁標題(title)動態改變
※「Open Source」負載均衡之Nginx
TAG:達人科技 |
※Springboot2.X之切換使用Servlet容器Jetty、Tomcat、Undertow
※Logging Servlet for changing Log Level at Runtime-Log4j2
※SpringBoot 2的普通servlet與WebFlux性能對比
※Servlet和Filter的生命周期
※Spring MVC之DispatcherServlet初始化詳解
※servlet各版本區別以及dynamic web module 版本之間的區別
※Servlet Cookie 處理
※Eclipse JSP/Servlet 環境搭建
※Servlet 包
※Tomcat+Servlet面試題都在這裡
※Servlet 簡介
※Jsp和Servlet有什麼區別?
※Servlet中幾個監聽器Listener的使用實例
※Servlet+MyBatis項目轉Spring Cloud微服務,多數據配置修改建議
※通過了解Servlet和Http之間的關係,了解web中http通信使用
※Servlet 國際化
※Servlet 處理日期
※Servlet 調試
※Servlet 環境設置
※SpringMVC如何與Servlet3整合在一起