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


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

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

項目說明

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

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

一、先引入pom文件

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

<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.60</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

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

spring:
  profiles:
    active: prod
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

三、創建實體類

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

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

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

public interface ChatFriendsMapper {
    //查詢所有的好友
    List<ChatFriends> LookUserAllFriends(String userid);
    //插入好友
    void InsertUserFriend(ChatFriends chatFriends);
    //判斷是否加好友
    Integer JustTwoUserIsFriend(ChatFriends chatFriends);
    //查詢用戶的信息
    Userinfo LkUserinfoByUserid(String userid);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chat.mapper.ChatFriendsMapper">
    <select id="LookUserAllFriends" resultType="com.chat.bean.ChatFriends" parameterType="java.lang.String">
      select userid,nickname,uimg from userinfo where userid in (select a.fuserid from chat_friends a where a.userid=#{userid})
    </select>
    <insert id="InsertUserFriend" parameterType="com.chat.bean.ChatFriends">
        insert into chat_friends (userid, fuserid) value (#{userid},#{fuserid})
    </insert>
    <select id="JustTwoUserIsFriend" parameterType="com.chat.bean.ChatFriends" resultType="java.lang.Integer">
        select id from chat_friends where userid=#{userid} and fuserid=#{fuserid}
    </select>
    <select id="LkUserinfoByUserid" parameterType="java.lang.String" resultType="com.chat.bean.Userinfo">
        select * from userinfo where userid=#{userid}
    </select>
</mapper>

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

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

@Service
public class ChatFriendsService {
    @Autowired
    ChatFriendsMapper chatFriendsMapper;
    public List<ChatFriends> 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);
    }
}

六、創建對應的控制器

這里再說說項目的接口

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

(同樣就只寫一個)

@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("登錄成功");
    }
}

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

  1. 表情過濾工具類
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);
    }

  1. Md5數據加密類
   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);
        }
    }
  1. 測試數據加密類
public class TestUtil {
    @Test
    public void testA(){
        String s = Md5Util.StringInMd5("123456");
        System.out.println(s);
    }
}

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

4

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

  1. Druid數據源
@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<String,String> 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<String,String> initParams=new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}
  1. 靜態資源以及攔截器
@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/*");
    }
}
  1. WebSocketConfigScokt通信配置
@Configuration
@EnableWebSocket
public class WebSocketConfig {
 
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

十、進行測試

這是兩個不同的用戶
7
8
當然了,還可以進行語音,添加好友
今天的就寫到這里吧!謝謝!
這里要提一下我的一個學長的個人博客,當然了,還有我的,謝謝

理木客

我的

天涯志


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM