发送系统通知
- 触发事件
- 评论后,发布通知
- 点赞后,发布通知
- 关注后,发布通知
- 处理事件
- 封装事件对象
- 开发事件的生产者
- 开发事件的消费者
1.封装事件对象:
import java.util.HashMap;
import java.util.Map;
public class Event {
private String topic;
private int userId;
private int entityType;
private int entityId;
private int entityUserId;
private Map<String,Object> data=new HashMap<>();
public String getTopic() {
return topic;
}
public Event setTopic(String topic) {
this.topic = topic;
return this;
}
public int getUserId() {
return userId;
}
public Event setUserId(int userId) {
this.userId = userId;
return this;
}
public int getEntityType() {
return entityType;
}
public Event setEntityType(int entityType) {
this.entityType = entityType;
return this;
}
public int getEntityId() {
return entityId;
}
public Event setEntityId(int entityId) {
this.entityId = entityId;
return this;
}
public int getEntityUserId() {
return entityUserId;
}
public Event setEntityUserId(int entityUserId) {
this.entityUserId = entityUserId;
return this;
}
public Map<String, Object> getData() {
return data;
}
public Event setData(String key, Object value) {
this.data.put(key, value);
return this;
}
}
2.开发事件的生产者
import com.alibaba.fastjson.JSONObject;
import com.nowcoder.community.entity.Event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
@Component
public class EventProducer {
@Autowired
private KafkaTemplate kafkaTemplate;
//处理事件
public void fireEvent(Event event){
//将事件发布到指定的主题
kafkaTemplate.send(event.getTopic(), JSONObject.toJSONString(event));
}
}
3.开发事件的消费者
import com.alibaba.fastjson.JSONObject;
import com.nowcoder.community.entity.Event;
import com.nowcoder.community.entity.Message;
import com.nowcoder.community.service.MessageServiceImpl;
import com.nowcoder.community.util.CommunityConstant;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class EventConsumer implements CommunityConstant {
private static final Logger logger= LoggerFactory.getLogger(EventConsumer.class);
@Autowired
private MessageServiceImpl messageService;
@KafkaListener(topics = {TOPIC_COMMENT,TOPIC_FOLLOW,TOPIC_LIKE})
public void handleCommentMessage(ConsumerRecord record){
if (record==null||record.value()==null){
logger.error("消息的内容为空!");
return;
}
Event event= JSONObject.parseObject(record.value().toString(),Event.class);
if (event==null){
logger.error("消息格式错误!");
return;
}
//发送站内通知
Message message=new Message();
message.setFromId(SYSTEM_USER_ID);
message.setToId(event.getEntityUserId());
message.setConversationId(event.getTopic());
message.setCreateTime(new Date());
Map<String,Object> content=new HashMap<>();
content.put("userId",event.getUserId());
content.put("entityType",event.getEntityType());
content.put("entityId",event.getEntityId());
if (!event.getData().isEmpty()){
for (Map.Entry<String, Object> entry : event.getData().entrySet()) {
content.put(entry.getKey(), entry.getValue());
}
}
message.setContent(JSONObject.toJSONString(content));
messageService.addMessage(message);
}
}
4.处理不同Controller(comment、like、follow):
CommentController:
import com.nowcoder.community.entity.Comment;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.Event;
import com.nowcoder.community.event.EventProducer;
import com.nowcoder.community.service.CommentServiceImpl;
import com.nowcoder.community.service.DiscussPostServiceImpl;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Date;
@Controller
@RequestMapping("/comment")
public class CommentController implements CommunityConstant {
@Autowired
private CommentServiceImpl commentService;
@Autowired
private HostHolder hostHolder;
@Autowired
private EventProducer eventProducer;
@Autowired
private DiscussPostServiceImpl discussPostService;
@PostMapping("/add/{discussPostId}")
public String addComment(@PathVariable("discussPostId") int discussPostId, Comment comment){
comment.setUserId(hostHolder.getUser().getId());
comment.setStatus(0);
comment.setCreateTime(new Date());
commentService.addComment(comment);
//触发评论事件
Event event=new Event()
.setTopic(TOPIC_COMMENT)
.setUserId(hostHolder.getUser().getId())
.setEntityType(comment.getEntityType())
.setEntityId(comment.getEntityId())
.setData("postId",discussPostId);
if (comment.getEntityType()==ENTITY_TYPE_POST){
DiscussPost post = discussPostService.selectDiscussPostById(comment.getEntityId());
event.setEntityUserId(post.getUserId());
}else if (comment.getEntityType()==ENTITY_TYPE_COMMENT){
Comment comment1 = commentService.selectCommentById(comment.getEntityId());
event.setEntityUserId(comment1.getUserId());
}
eventProducer.fireEvent(event);
return "redirect:/discuss/detail/"+discussPostId;
}
}
LikeController:
import com.nowcoder.community.entity.Event;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.event.EventProducer;
import com.nowcoder.community.service.LikeService;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
@Controller
public class LikeController implements CommunityConstant {
@Autowired
private HostHolder hostHolder;
@Autowired
private LikeService likeService;
@Autowired
private EventProducer eventProducer;
@PostMapping("/like")
@ResponseBody
public String like(int entityType,int entityId,int entityUserId,int postId){
User user = hostHolder.getUser();
//点赞
likeService.like(user.getId(), entityType,entityId,entityUserId);
//点赞数量
long likeCount = likeService.selectEntityLikeCount(entityType, entityId);
//点赞状态
int likeStatus = likeService.selectEntityLikeStatus(user.getId(), entityType, entityId);
//返回的结果,用Map封装
Map<String,Object> map=new HashMap<>();
map.put("likeCount",likeCount);
map.put("likeStatus",likeStatus);
//触发点赞事件
if (likeStatus==1){
Event event=new Event()
.setTopic(TOPIC_LIKE)
.setUserId(hostHolder.getUser().getId())
.setEntityType(entityType)
.setEntityId(entityId)
.setEntityUserId(entityUserId)
.setData("postId",postId);
eventProducer.fireEvent(event);
}
return CommunityUtil.getJSONString(0,null,map);
}
}
FollowController:
import com.nowcoder.community.entity.Event;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.event.EventProducer;
import com.nowcoder.community.service.FollowService;
import com.nowcoder.community.service.UserServiceImpl;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
@Controller
public class FollowController implements CommunityConstant {
@Autowired
private FollowService followService;
@Autowired
private HostHolder hostHolder;
@Autowired
private UserServiceImpl userService;
@Autowired
private EventProducer eventProducer;
@PostMapping("/follow")
@ResponseBody
public String follow(int entityType,int entityId){
User user = hostHolder.getUser();
followService.follow(user.getId(), entityType,entityId);
//触发关注事件
Event event=new Event()
.setTopic(TOPIC_FOLLOW)
.setUserId(hostHolder.getUser().getId())
.setEntityType(entityType)
.setEntityId(entityId)
.setEntityUserId(entityId);
eventProducer.fireEvent(event);
return CommunityUtil.getJSONString(0,"已关注");
}
@PostMapping("/unfollow")
@ResponseBody
public String unfollow(int entityType,int entityId){
User user = hostHolder.getUser();
followService.unfollow(user.getId(), entityType,entityId);
return CommunityUtil.getJSONString(0,"已取消关注");
}
private boolean hasFollowed(int userId){
if (hostHolder.getUser()==null){
return false;
}
return followService.hasFollowed(hostHolder.getUser().getId(), CommunityConstant.ENTITY_TYPE_USER,userId);
}
@GetMapping("/followees/{userId}")
public String getFollowees(@PathVariable("userId") int userId, Page page, Model model){
User user = userService.selectById(userId);
if (user==null){
throw new RuntimeException("该用户不存在!");
}
model.addAttribute("user",user);
page.setPath("/followees/"+userId);
page.setLimit(5);
page.setRows((int) followService.selectFolloweeCount(userId,CommunityConstant.ENTITY_TYPE_USER));
List<Map<String, Object>> userList = followService.selectFollowees(userId, page.getOffset(), page.getLimit());
if (userList!=null){
for (Map<String, Object> map : userList) {
User u = (User) map.get("user");
map.put("hasFollowed",hasFollowed(u.getId()));
}
}
model.addAttribute("users",userList);
return "/site/followee";
}
@GetMapping("/followers/{userId}")
public String getFollowers(@PathVariable("userId") int userId,Page page,Model model){
User user = userService.selectById(userId);
if (user==null){
throw new RuntimeException("该用户不存在!");
}
model.addAttribute("user",user);
page.setLimit(5);
page.setPath("/followers/"+userId);
page.setRows((int) followService.selectFollowerCount(CommunityConstant.ENTITY_TYPE_USER,userId));
List<Map<String, Object>> userList = followService.selectFollowers(userId, page.getOffset(), page.getLimit());
if (userList!=null){
for (Map<String, Object> map : userList) {
User u = (User) map.get("user");
map.put("hasFollowed",hasFollowed(u.getId()));
}
}
model.addAttribute("users",userList);
return "/site/follower";
}
}