SpringbootとWebScoketに基づくオンラインチャットアプレット
(私は数日間何も書いておらず、手を練習していなかったので、これを見ただけです...)
プロジェクト指導
- このプロジェクトは、springboot + websocket + vueによって開発されたチャット用の小さなデモです。
- インターフェースの1つは友達追加インターフェースです。友達を追加すると、その友達がすでに友達であるかどうかが決まります。
- チャット時:AはBにメッセージを送信します。BのチャットウィンドウがAでない場合、BはAにメッセージを送信するよう通知します。
- チャットコンテンツの入力ボックスは、layuiのリッチテキストエディターを使用しており、コンテンツを送信するためのキャリッジリターンを現在サポートしていません。
- チャットは写真を送信でき、写真はデフォルトでD:/ chat /ディレクトリに保存されます。
- チャットコンテンツの画像をクリックすると、プレビューがポップアップ表示され、このメッセージのすべての画像がポップアップ表示されます。
- 音声を送信する場合、デフォルトでは現在のチャットウィンドウでユーザーに音声が送信されるため、音声を録音するときは、現在のチャットウィンドウでユーザーが選択されていることを確認してください。
- ユーザーのアカウントで友達を追加できることを確認してください。現在、アカウントが存在する場合は、直接追加できます。
古いルールでは、最初に小さなプロジェクトのディレクトリ構造を見てみましょう:
まず、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/**/*.xmlserver: session: timeout: 7200
3、エンティティクラスを作成する
ここではこれ以上説明しません。Login、Userinfo、ChatMsg、ChatFriendsがあります。
4番目に、対応するマッパー(つまり、DAOレイヤー)と対応するマッパーマッピングファイルを作成します。
(これは1つだけです。これ以上は言いません)
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>
5、対応するビジネスクラス(つまり、サービス)を作成する
(同じビジネス層もここで指摘されています)
@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);
}}
6、対応するコントローラーを作成する
プロジェクトのインターフェースについてお話しましょう
- / chat / upimgチャット画像アップロードインターフェイス
- / chat / lkuserこのインターフェイスを使用して友達を追加します。ユーザーを照会し、ユーザーが存在する場合はユーザー情報を返し、存在しない場合は存在しないを返します。
- / chat / adduser /このインターフェースは友達を追加するためのインターフェースであり、追加された友達が自分であるかどうかを判別します。追加された友達がすでに存在する場合は、直接戻ります
- / chat / ctチャットインターフェイスにジャンプします
- / chat / lkfriendsユーザーの友達を照会
- / chat / lkuschatmsg /このインターフェースは、2人のユーザー間のチャット情報を照会し、ユーザーのユーザーIDを渡して、現在ログインしているユーザーとユーザーのチャット履歴を照会するためのインターフェースです。
- / chat / audioこのインターフェイスは、Webインターフェイスjsによって記録されたオーディオデータをアップロードするためにAjaxによって使用されます
(また、1つだけ書いてください)
@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("登录成功");
}}
7、対応するツールクラスとカスタム例外クラスを作成する
- 式フィルタリングツール
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); }
- 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); } }
- データ暗号化のテスト
public class TestUtil {
@Test
public void testA(){
String s = Md5Util.StringInMd5("123456");
System.out.println(s);
}}
8.対応する静的リソースファイルをインポートします(これは最初に行う必要があります)
9、いくつかの構成をカスタマイズし、それらをコンテナーに注入する
- ドルイドのデータソース
@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;
}}
- 静的リソースとインターセプター
@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/*");
}}
- WebSocketConfigScokt通信配置
@Configuration
@EnableWebSocket
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter();
}}
10.テスト
これらは2人の異なるユーザーです
もちろん、声を出したり、友達を 追加したり、今日ここに書いたりすることもでき ます!ありがとうございました!もちろん私の先輩の一人の個人的なブログに触れたいと思います、そして私のもの、ありがとう
著者:考える牛乳
リンク:https://juejin.im/post/5ea7994c5188256da14e972d
出典:ナゲット