目录
一,mybatis-plus实战一
1.导入依赖
2.application.yml配置
3.实体类
4.mapper
5.service层
6.启动类上配置
二,mybatis-plus实战二
1.导入依赖
2.application.yml配置
3.实体类
2.mapper
3.service
4.分页配置
5.放一个在controller层实现的mybatis-plus的具体实现
6.启动类上加上注解
三,时间更新全局配置(自定义元数据对象处理器)
1.数据库相关字段配置
2. 实体类配置
四.WebSocket打造在线聊天室
1.导入依赖
2.配置类
3.工具类
4.controller
5.index.html
一,mybatis-plus实战一
1.导入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
2.application.yml配置
spring:
# 配置数据源信息
datasource:
# 配置数据源类型
type: com.zaxxer.hikari.HikariDataSource
# 配置连接数据库的各个信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/intrest?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: 12345678
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# # 设置MyBatis-Plus的全局配置
# global-config:
# db-config:
# # 设置实体类所对应的表的统一前缀
# table-prefix: t_
# # 设置统一的主键生成策略
# id-type: auto
# # 配置类型别名所对应的包
type-aliases-package: com.interest.pojo
# # 扫描通用枚举的
# 包
# type-enums-package: com.interest.enums
3.实体类
package com.interest.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author a1002
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("interest")
public class Interest {
@JsonSerialize(using = ToStringSerializer.class)
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
private String code;
private String name;
private String sex;
private String birthday;
private String phone;
private String type;
private String course;
private String registerTime;
private String remaining;
private String score;
public Interest(String code, String name, String sex, String birthday, String phone, String type, String course, String registerTime, String remaining, String score) {
this.code = code;
this.name = name;
this.sex = sex;
this.birthday = birthday;
this.phone = phone;
this.type = type;
this.course = course;
this.registerTime = registerTime;
this.remaining = remaining;
this.score = score;
}
}
4.mapper
package com.interest.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.interest.pojo.Interest;
import org.springframework.stereotype.Repository;
/**
* @author a1002
*/
@Repository
public interface InterestMapper extends BaseMapper<Interest> {
}
5.service层
package com.interest.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.interest.config.Response;
import com.interest.pojo.Interest;
import java.util.List;
import java.util.Map;
/**
* @author a1002
*/
public interface InterestService extends IService<Interest> {
}
package com.interest.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.interest.config.Response;
import com.interest.mapper.InterestMapper;
import com.interest.pojo.Interest;
import com.interest.service.InterestService;
import com.interest.utils.IDutils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author a1002
*/
@Service
public class InterestServiceImpl extends ServiceImpl<InterestMapper,Interest> implements InterestService {
}
6.启动类上配置
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author a1002
*/
@Slf4j
@SpringBootApplication
//@ServletComponentScan
@EnableTransactionManagement
@EnableCaching
@MapperScan("com.blog.mapper")
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
log.info("项目启动成功...");
}
}
二,mybatis-plus实战二
1.导入依赖
<!--mybaties-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
2.application.yml配置
mybatis-plus:
configuration:
#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: ASSIGN_ID
3.实体类
import lombok.Data;
import java.io.Serializable;
@Data
public class Orders implements Serializable {
}
2.mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yangeat.entity.AddressBook;
import org.apache.ibatis.annotations.Mapper;
/**
* @author a1002
*/
@Mapper
public interface AddressBookMapper extends BaseMapper<AddressBook> {
}
3.service
import com.baomidou.mybatisplus.extension.service.IService;
import com.yangeat.entity.AddressBook;
/**
* @author a1002
*/
public interface AddressBookService extends IService<AddressBook> {
}
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yangeat.entity.AddressBook;
import com.yangeat.mapper.AddressBookMapper;
import com.yangeat.service.AddressBookService;
import org.springframework.stereotype.Service;
/**
* @author a1002
*/
@Service
public class AddressBookServiceImpl extends ServiceImpl<AddressBookMapper, AddressBook> implements AddressBookService {
}
4.分页配置
package com.blog.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 配置MP的分页插件
*
* @author a1002
*/
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
分页实际应用:
@Override
public R list(int page, int size, String name) {
Page<User> pageInfo = new Page<>(page, size);
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(name != null, User::getUsername, name);
queryWrapper.orderByDesc(User::getUpdateTime);
userService.page(pageInfo, queryWrapper);
return R.success(pageInfo);
}
5.放一个在controller层实现的mybatis-plus的具体实现
package com.yangeat.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yangeat.common.R;
import com.yangeat.dto.SetmealDto;
import com.yangeat.entity.Category;
import com.yangeat.entity.Setmeal;
import com.yangeat.service.CategoryService;
import com.yangeat.service.SetmealDishService;
import com.yangeat.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* 套餐管理
*/
@RestController
@RequestMapping("/setmeal")
@Slf4j
public class SetmealController {
@Autowired
private SetmealService setmealService;
@Autowired
private CategoryService categoryService;
@Autowired
private SetmealDishService setmealDishService;
/**
* 新增套餐
*
* @param setmealDto
* @return
*/
@PostMapping
public R<String> save(@RequestBody SetmealDto setmealDto) {
log.info("套餐信息:{}", setmealDto);
setmealService.saveWithDish(setmealDto);
return R.success("新增套餐成功");
}
/**
* 套餐分页查询
*
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R<Page> page(int page, int pageSize, String name) {
//分页构造器对象
Page<Setmeal> pageInfo = new Page<>(page, pageSize);
Page<SetmealDto> dtoPage = new Page<>();
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
//添加查询条件,根据name进行like模糊查询
queryWrapper.like(name != null, Setmeal::getName, name);
//添加排序条件,根据更新时间降序排列
queryWrapper.orderByDesc(Setmeal::getUpdateTime);
setmealService.page(pageInfo, queryWrapper);
//对象拷贝
BeanUtils.copyProperties(pageInfo, dtoPage, "records");
List<Setmeal> records = pageInfo.getRecords();
List<SetmealDto> list = records.stream().map((item) -> {
SetmealDto setmealDto = new SetmealDto();
//对象拷贝
BeanUtils.copyProperties(item, setmealDto);
//分类id
Long categoryId = item.getCategoryId();
//根据分类id查询分类对象
Category category = categoryService.getById(categoryId);
if (category != null) {
//分类名称
String categoryName = category.getName();
setmealDto.setCategoryName(categoryName);
}
return setmealDto;
}).collect(Collectors.toList());
dtoPage.setRecords(list);
return R.success(dtoPage);
}
/**
* 删除套餐
*
* @param ids
* @return
*/
@DeleteMapping
public R<String> delete(@RequestParam List<Long> ids) {
log.info("ids:{}", ids);
setmealService.removeWithDish(ids);
return R.success("套餐数据删除成功");
}
// @GetMapping("/list")
// public R<List<Setmeal>> list(Setmeal setmeal) {
// log.info("setmeal:{}", setmeal);
// //条件构造器
// LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
// queryWrapper.like(StringUtils.isNotEmpty(setmeal.getName()), Setmeal::getName, setmeal.getName());
// queryWrapper.eq(null != setmeal.getCategoryId(), Setmeal::getCategoryId, setmeal.getCategoryId());
// queryWrapper.eq(null != setmeal.getStatus(), Setmeal::getStatus, setmeal.getStatus());
// queryWrapper.orderByDesc(Setmeal::getUpdateTime);
//
// return R.success(setmealService.list(queryWrapper));
// }
/**
* 根据条件查询套餐数据
*
* @param setmeal
* @return
*/
@GetMapping("/list")
public R<List<Setmeal>> list1(@RequestBody Setmeal setmeal) {
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
queryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus());
queryWrapper.orderByDesc(Setmeal::getUpdateTime);
List<Setmeal> list = setmealService.list(queryWrapper);
return R.success(list);
}
@PostMapping("/status/{status}")
public R<List<Setmeal>> status(@PathVariable Integer status, @RequestParam List<Long> ids) {
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(Setmeal::getId, ids);
List<Setmeal> list = setmealService.list(queryWrapper);
List<Setmeal> list1 = list.stream().map((item) -> {
item.setStatus(status);
return item;
}).collect(Collectors.toList());
setmealService.updateBatchById(list1);
return R.success(list1);
}
}
6.启动类上加上注解
主要是@ServletComponentScan这个注解
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author a1002
*/
@Slf4j
@SpringBootApplication
@ServletComponentScan
@EnableTransactionManagement
public class YangEatApplication {
public static void main(String[] args) {
SpringApplication.run(YangEatApplication.class, args);
log.info("项目启动成功...");
}
}
三,时间更新全局配置(自定义元数据对象处理器)
1.数据库相关字段配置
2. 实体类配置
package com.blog.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author a1002
*/
@SuppressWarnings("all")
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String username;
private String password;
/**
* 0是用户
* 1是管理员
*/
private Integer status;
private String img;
private String blogPath;
private String grade;
//创建时间
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
//更新时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
//创建人
@TableField(fill = FieldFill.INSERT)
private Long createUser;
//修改人
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User(Long id, String username, String password, String img, String blogPath, String grade) {
this.id = id;
this.username = username;
this.password = password;
this.img = img;
this.blogPath = blogPath;
this.grade = grade;
}
public User(Long id, String username, String password, String blogPath, String grade) {
this.id = id;
this.username = username;
this.password = password;
this.blogPath = blogPath;
this.grade = grade;
}
}
其中主要是这些字段
//创建时间
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
//更新时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
//创建人
@TableField(fill = FieldFill.INSERT)
private Long createUser;
//修改人
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
相关配置:
主要是这三个配置类:
package com.blog.common;
/**
* 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
*
* @author a1002
*/
public class BaseContext {
private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
/**
* 设置值
*
* @param id
*/
public static void setCurrentId(Long id) {
threadLocal.set(id);
}
/**
* 获取值
*
* @return
*/
public static Long getCurrentId() {
return threadLocal.get();
}
}
package com.blog.common;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
*
* @author a1002
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}
package com.blog.common;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* 自定义元数据对象处理器
*
* @author a1002
*/
@Component
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler {
/**
* 插入操作,自动填充
*
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
log.info("公共字段自动填充[insert]...");
log.info(metaObject.toString());
metaObject.setValue("createTime", LocalDateTime.now());
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("createUser", BaseContext.getCurrentId());
metaObject.setValue("updateUser", BaseContext.getCurrentId());
}
/**
* 更新操作,自动填充
*
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
log.info("公共字段自动填充[update]...");
log.info(metaObject.toString());
long id = Thread.currentThread().getId();
log.info("线程id为:{}", id);
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("updateUser", BaseContext.getCurrentId());
}
}
GlobalExceptionHandler是针对添加用户时避免用户重复添加的异常处理
package com.blog.common;
import com.blog.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.sql.SQLIntegrityConstraintViolationException;
/**
* 全局异常处理
*
* @author a1002
*/
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {
/**
* 异常处理方法
*
* @return
*/
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex) {
log.error(ex.getMessage());
if (ex.getMessage().contains("Duplicate entry")) {
String[] split = ex.getMessage().split(" ");
String msg = split[2] + "已存在";
return R.error(msg);
}
return R.error("未知错误");
}
// /**
// * 异常处理方法
// *
// * @return
// */
// @ExceptionHandler(CustomException.class)
// public R<String> exceptionHandler(CustomException ex) {
// log.error(ex.getMessage());
//
// return R.error(ex.getMessage());
// }
}
四.WebSocket打造在线聊天室
目录
1.导入依赖
<!--websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.7.2</version>
</dependency>
2.配置类
package com.websockettest.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.websocket.server.ServerEndpointConfig;
/**
* @author a1002
*/
public class MySpringConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {
private static volatile BeanFactory context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
MySpringConfigurator.context = applicationContext;
}
@Override
public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
return context.getBean(clazz);
}
}
package com.websockettest.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author a1002
*/
@Configuration
@ConditionalOnWebApplication
public class WebSocketConfig {
//使用boot内置tomcat时需要注入此bean
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
@Bean
public MySpringConfigurator mySpringConfigurator() {
return new MySpringConfigurator();
}
}
3.工具类
package com.websockettest.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author a1002
*/
public class DateUtils {
public static String getDate() {
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
return format.format(date);
}
}
4.controller
package com.websockettest.controller;
import com.websockettest.config.MySpringConfigurator;
import com.websockettest.utils.DateUtils;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
/**
* @author a1002
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
*/
@ServerEndpoint(value = "/chat/{uid}", configurator = MySpringConfigurator.class)
@Component
public class WebSocketTest {
private Session session;
private String getUid(Session session) {
this.session = session;
Map parem = session.getPathParameters();
String uid = parem.get("uid").toString();
return uid;
}
/**
* 当前登录人的 session 管理器
*/
private static Map<String, Session> sessionMessage = new HashMap<>();
@OnOpen//打开连接执行
public void onOpw(Session session) {
String uid = getUid(session);
sessionMessage.put(uid, session);
System.out.println("[" + uid + "] 进入聊天室");
sendMessage("[" + uid + "] 进入聊天室");
}
@OnMessage//收到消息执行
public void onMessage(String message, Session session) {
String uid = getUid(session);
sendMessage(uid + " (" + DateUtils.getDate() + ") 说: " + message);
}
@OnClose//关闭连接执行
public void onClose(Session session) {
System.out.println(session.getId() + "关闭连接");
}
@OnError//连接错误的时候执行
public void onError(Throwable error, Session session) {
System.out.println("错误的时候执行");
error.printStackTrace();
}
/**
* 发送消息
*
* @param message
*/
public void sendMessage(String message) {
for (String uid : sessionMessage.keySet()) {
try {
sessionMessage.get(uid).getAsyncRemote().sendText(message);
} catch (Exception e) {
}
}
}
}
5.index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>欢迎来到聊天室</title>
</head>
<body>
Welcome<br/> <span id="yhm"></span>
<div id="div1">
<input id="account" type="text" placeholder="用户名"/>
<button onclick="init()">连接聊天室</button>
<hr/>
</div>
<div id="div2" hidden>
<input id="text" type="text"/>
<button onclick="send()">发送消息</button>
<hr/>
</div>
<div id="message"></div>
</body>
<script type="text/javascript">
var websocaket = null;
function init() {
var account = document.getElementById("account").value;
if (account == '') {
setdivInnerHTML("没有输入UID");
return false;
}
if ('WebSocket' in window) {
websocaket = new WebSocket("ws://110.40.210.213:8848/chat/" + account);//用于创建 WebSocket 对象。WebSocketTest对应的是java类的注解值
} else {
setdivInnerHTML("当前浏览器不支持");
}
//连接发生错误的时候回调方法;
websocaket.onerror = function () {
setdivInnerHTML("连接错误");
}
//连接成功时建立回调方法;
websocaket.onopen = function () {
document.getElementById("div2").hidden = false;
document.getElementById("div1").hidden = true;
document.getElementById("yhm").text(account);
setdivInnerHTML("连接成功");
}
//收到消息的回调方法
websocaket.onmessage = function (msg) {
setdivInnerHTML(msg.data);
}
//连接关闭的回调方法
websocaket.onclose = function () {
setdivInnerHTML("关闭成功");
}
}
//关闭websocket
//
function closea() {
websocaket.close();
alert("点击关闭");
}
function setdivInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
function send() {
var message = document.getElementById('text').value;
websocaket.send(message);//给后台发送数据
}
</script>
</html>