實在!基於Springboot和WebScoket,寫了一個在線聊天小程序

基於Springboot和WebScoket寫的一個在線聊天小程序

(好幾天沒有寫東西了,也沒有去練手了,就看了看這個。。。)

項目說明

此項目為一個聊天的小demo,採用springboot+websocket+vue開發。其中有一個接口為添加好友接口,添加好友會判斷是否已經是好友。聊天的時候:A給B發送消息如果B的聊天窗口不是A,則B處會提醒A發來一條消息。聊天內容的輸入框採用layui的富文本編輯器,目前不支持回車發送內容。聊天可以發送圖片,圖片默認存儲在D:/chat/目錄下。點擊聊天內容中的圖片會彈出預覽,這個預覽彈出此條消息中的所有圖片。在發送語音的時候,語音默認發送給當前聊天窗口的用戶,所以錄製語音的時候務必保證當前聊天窗口有選擇的用戶。知道用戶的賬號可以添加好友,目前是如果賬號存在,可以直接添加成功

老規矩,還是先看看小項目的目錄結構:

一、先引入pom文件

這裡就只放了一點點代碼(代碼太長了)

<code> commons-io commons-io 2.4 org.projectlombok lombok net.sf.json-lib json-lib 2.4 jdk15 org.springframework.boot spring-boot-starter-thymeleaf 2.2.4.RELEASE com.alibaba fastjson 1.2.60 org.springframework.boot spring-boot-starter-test test /<code>

二、創建對應的yml配置文件

<code>spring: profiles: active: prod/<code>

<code>spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/chat?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=UTC driver-class-name: com.mysql.jdbc.Driver #指定數據源 type: com.alibaba.druid.pool.DruidDataSource # 數據源其他配置 initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true # 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用於防火牆 filters: stat,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 thymeleaf: suffix: .html prefix: classpath: /templates/ cache: false jackson: #返回的日期字段的格式 date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 serialization: write-dates-as-timestamps: false # true 使用時間戳顯示時間 http: multipart: max-file-size: 1000Mb max-request-size: 1000Mb #配置文件式開發 mybatis: #全局配置文件的位置 config-location: classpath:mybatis/mybatis-config.xml #所有sql映射配置文件的位置 mapper-locations: classpath:mybatis/mapper/**/*.xml server: session: timeout: 7200/<code>

三、創建實體類

這裡就不再多說了,有Login,Userinfo,ChatMsg,ChatFriends

四、創建對應的mapper(即dao層)還有對應的mapper映射文件

(這裡就舉出了一個,不再多說)

<code>public interface ChatFriendsMapper { //查詢所有的好友 List LookUserAllFriends(String userid); //插入好友 void InsertUserFriend(ChatFriends chatFriends); //判斷是否加好友 Integer JustTwoUserIsFriend(ChatFriends chatFriends); //查詢用戶的信息 Userinfo LkUserinfoByUserid(String userid); }/<code>

<code> insert into chat_friends (userid, fuserid) value (#{userid},#{fuserid}) /<code>

五、創建對應的業務類(即service)

(同樣的業務層這裡也就指出一個)

<code>@Service public class ChatFriendsService { @Autowired ChatFriendsMapper chatFriendsMapper; public List LookUserAllFriends(String userid){ return chatFriendsMapper.LookUserAllFriends(userid); } public void InsertUserFriend(ChatFriends chatFriends){ chatFriendsMapper.InsertUserFriend(chatFriends); } public Integer JustTwoUserIsFriend(ChatFriends chatFriends){ return chatFriendsMapper.JustTwoUserIsFriend(chatFriends); } public Userinfo LkUserinfoByUserid(String userid){ return chatFriendsMapper.LkUserinfoByUserid(userid); } } /<code>

六、創建對應的控制器

這裡再說說項目的接口

/chat/upimg 聊天圖片上傳接口/chat/lkuser 這個接口用來添加好友的時候:查詢用戶,如果用戶存在返回用戶信息,如果不存在返回不存在/chat/adduser/ 這個接口是添加好友接口,會判斷添加的好友是否是自己,如果添加的好友已經存在則直接返回/chat/ct 跳轉到聊天界面/chat/lkfriends 查詢用戶的好友/chat/lkuschatmsg/ 這個接口是查詢兩個用戶之間的聊天信息的接口,傳入用戶的userid,查詢當前登錄用戶和該用戶的聊天記錄。/chat/audio 這個接口是Ajax上傳web界面js錄製的音頻數據用的接口

(同樣就只寫一個)

<code>@Controller public class LoginCtrl { @Autowired LoginService loginService; @GetMapping("/") public String tologin(){ return "user/login"; } /** * 登陸 * */ @PostMapping("/justlogin") @ResponseBody public R login(@RequestBody Login login, HttpSession session){ login.setPassword(Md5Util.StringInMd5(login.getPassword())); String userid = loginService.justLogin(login); if(userid==null){ return R.error().message("賬號或者密碼錯誤"); } session.setAttribute("userid",userid); return R.ok().message("登錄成功"); } } /<code>

七、創建對應的工具類以及自定義異常類

表情過濾工具類

<code>public class EmojiFilter { private static boolean isEmojiCharacter(char codePoint) { return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD) || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)); } @Test public void testA(){ String s = EmojiFilter.filterEmoji("您好,你好啊"); System.out.println(s); } /<code>Md5數據加密類

<code> static String[] chars = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}; /** * 將普通字符串用md5加密,並轉化為16進制字符串 * @param str * @return */ public static String StringInMd5(String str) { // 消息簽名(摘要) MessageDigest md5 = null; try { // 參數代表的是算法名稱 md5 = MessageDigest.getInstance("md5"); byte[] result = md5.digest(str.getBytes()); StringBuilder sb = new StringBuilder(32); // 將結果轉為16進制字符 0~9 A~F for (int i = 0; i < result.length; i++) { // 一個字節對應兩個字符 byte x = result[i]; // 取得高位 int h = 0x0f & (x >>> 4); // 取得低位 int l = 0x0f & x; sb.append(chars[h]).append(chars[l]); } return sb.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }/<code>測試數據加密類

<code>public class TestUtil { @Test public void testA(){ String s = Md5Util.StringInMd5("123456"); System.out.println(s); } } /<code>

八、引入對應的靜態資源文件(這個應該一開始就做的)

九、自定義一些配置並且注入到容器裡面

Druid數據源

<code>@Configuration public class DruidConfig { @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druid(){ return new DruidDataSource(); } //配置Druid的監控 //1.配置要給管理後臺的Servlet @Bean public ServletRegistrationBean servletRegistrationBean(){ ServletRegistrationBean bean=new ServletRegistrationBean(new StatViewServlet(),"/druid/*"); Map initParams=new HashMap<>(); initParams.put("loginUsername","admin"); initParams.put("loginPassword","admin233215"); initParams.put("allow","");//默認允許ip訪問 initParams.put("deny",""); bean.setInitParameters(initParams); return bean; } //2.配置一個監控的filter @Bean public FilterRegistrationBean webStarFilter(){ FilterRegistrationBean bean=new FilterRegistrationBean(); bean.setFilter(new WebStatFilter()); Map initParams=new HashMap<>(); initParams.put("exclusions","*.js,*.css,/druid/*"); bean.setInitParameters(initParams); bean.setUrlPatterns(Arrays.asList("/*")); return bean; } }/<code>靜態資源以及攔截器

<code>@Configuration public class MyConfig extends WebMvcConfigurerAdapter { //配置一個靜態文件的路徑 否則css和js無法使用,雖然默認的靜態資源是放在static下,但是沒有配置裡面的文件夾 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); } @Bean public WebMvcConfigurerAdapter WebMvcConfigurerAdapter() { WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //registry.addResourceHandler("/pic/**").addResourceLocations("file:D:/chat/"); registry.addResourceHandler("/pic/**").addResourceLocations("file:D:/idea_project/SpringBoot/Project/Complete&&Finish/chat/chatmsg/"); super.addResourceHandlers(registry); } }; return adapter; } @Override public void addInterceptors(InterceptorRegistry registry) { //註冊TestInterceptor攔截器 InterceptorRegistration registration = registry.addInterceptor(new AdminInterceptor()); registration.addPathPatterns("/chat/*"); } }/<code>WebSocketConfigScokt通信配置

<code>@Configuration @EnableWebSocket public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }/<code>

十、進行測試

這是兩個不同的用戶

當然了,還可以進行語音,添加好友 今天的就寫到這裡吧!謝謝! 這裡要提一下我的一個學長的個人博客,當然了,還有我的,謝謝

作者:奶思

鏈接:https://juejin.im/post/5ea7994c5188256da14e972d

來源:掘金