Based on Springboot and WebScoket to write an online chat small procedures
Project description
- This project is a small demo chat, using Springboot + Websocket + Vue development.
- One of the interfaces is the Add Friend interface, adding a friend will determine whether they are already friends.
- During chatting: USER A sends A message to user B. If user B’s chat window is not user A’s, user B will prompt user A to send A message.
- The input box of chat content adopts layui’s rich text editor, and currently does not support carriage return to send content.
- Chat can send pictures, which are stored in D:/chat/ by default.
- Clicking on an image in the chat brings up a preview that brings up all the images in the message.
- By default, voice messages are sent to users in the current chat window. Therefore, ensure that the selected users are available in the current chat window when recording voice messages.
- You can add friends if you know the user’s account. At present, you can add friends if the account exists
As usual, let’s look at the project directory structure first:
First, introduce poM files
I only put a little bit of code here (it’s too long)
<dependency> <groupId> Commons -io</groupId> <artifactId> Commons -io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> < the 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 > < the dependency > < groupId > com. Alibaba < / groupId > < artifactId > fastjson < / artifactId > < version > 1.2.60 < / version > < / dependency > < the dependency > <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>Copy the code
2. Create the corresponding YML configuration file
spring:
profiles:
active: prod
Copy the 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 # specify the data source type: com. Alibaba. Druid. Pool. The other configuration initialSize DruidDataSource # data source: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: True # configuration monitoring statistics of intercepting filters to remove the monitor interface after SQL is unable to statistics, 'wall' for firewall 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: HTTP: multipart: max-file-size: 1000Mb max-request-size: 1000Mb # the location of the global configuration file config - location: the classpath: mybatis/mybatis - config. # all SQL mapping XML configuration file location mapper - locations: classpath:mybatis/mapper/**/*.xmlserver: session: timeout: 7200Copy the code
Create an entity class
Here is no longer say more, with the Login, the Userinfo, ChatMsg, ChatFriends
Create the corresponding MAPper (dao layer) and the corresponding mapper mapping file
(Here is just one, no more details)
Public interface ChatFriendsMapper {// Query all friends List<ChatFriends> LookUserAllFriends(String userid); Void InsertUserFriend(ChatFriends ChatFriends); // Determine whether to add friends Integer JustTwoUserIsFriend(ChatFriends ChatFriends); // Query user information Userinfo LkUserinfoByUserid(String userid); }Copy the code
<? The 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>Copy the code
Create the corresponding business class (service)
(The same business layer is also pointed out here)
@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);
}}
Copy the code
6. Create a controller
Let’s talk about the project interface
- /chat/upimg Interface for uploading chat pictures
- The /chat/lkuser interface is used to add friends. If the user exists, the user information is returned. If the user does not exist, the user information is returned
- The /chat/adduser/ interface is used to add friends. It checks whether the added friend is the user and returns the value if the added friend already exists
- /chat/ct The chat page is displayed
- /chat/ lkFriends Queries a user’s friends
- /chat/lkuschatmsg/ This interface is used to query the chat information between two users. The user’s userID is passed in to query the chat records of the current logged-in user and the user.
- The /chat/audio interface is used by Ajax to upload audio data recorded by JS on the Web interface
(Again, just write one)
@Controller public class LoginCtrl { @Autowired LoginService loginService; @GetMapping("/") public String tologin(){ return "user/login"; } /** * @responseBody public R login(@requestBody login, HttpSession session){ login.setPassword(Md5Util.StringInMd5(login.getPassword())); String userid = loginService.justLogin(login); If (userID ==null){return r.ror ().message(" username or password error "); } session.setAttribute("userid",userid); Return r.ok ().message(" login succeeded "); }}Copy the code
Create the corresponding tool class and custom exception class
- Expression filtering tool class
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 (" hello :smile:, hello "); System.out.println(s); }Copy the code
- Md5 data encryption class
static String[] chars = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}; /** * use MD5 to encrypt ordinary strings, Convert to hexadecimal String * @param STR * @return */ public static String StringInMd5(String STR) {MessageDigest md5 = null; Try {/ / parameter represents the md5 algorithm name = MessageDigest. GetInstance (" md5 "); byte[] result = md5.digest(str.getBytes()); StringBuilder sb = new StringBuilder(32); A~F for (int I = 0; i < result.length; Int x = result[I]; int 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); }}Copy the code
- Test data encryption classes
public class TestUtil {
@Test
public void testA(){
String s = Md5Util.StringInMd5("123456");
System.out.println(s);
}}
Copy the code
8. Introduce the corresponding static resource file (this should be done at the beginning)
9. Customize some configurations and inject them into the container
- Druid data source
@Configuration public class DruidConfig { @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druid(){ return new DruidDataSource(); Public ServletRegistrationBean ServletRegistrationBean (){public 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",""); // Allow IP access to initparams. put("deny",""); bean.setInitParameters(initParams); return 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; }}Copy the code
- Static resources and interceptors
@configuration public class MyConfig extends WebMvcConfigurerAdapter {// Specify the path to a static file. @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/ch at/chatmsg/"); super.addResourceHandlers(registry); }}; return adapter; } @override public void addInterceptors(InterceptorRegistry registry) {TestInterceptor InterceptorRegistration registration = registry.addInterceptor(new AdminInterceptor()); registration.addPathPatterns("/chat/*"); }}Copy the code
- WebSocketConfigScokt Communication configuration
@Configuration
@EnableWebSocket
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter();
}}
Copy the code
10. Test
These are two different users
Of course, you can also make voice calls and add friends
That’s all for today! If you like, please pay attention to it. Thank you!