栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

第二章 开发社区核心功能(二)

Java 更新时间:发布时间: 百科书网 趣学号
第二章 开发社区核心功能(二) 私信列表

数据层
  • MessageMapper.java
@Mapper
public interface MessageMapper {

    // 查询当前用户的会话列表,针对每个会话只返回一条最新的私信
    List selectConversations(int userId, int offset, int limit);

    // 查询当前用户的会话数量
    int selectConversationCount(int userId);

    // 查询某个会话所包含的私信列表
    List selectLetters(String conversationId, int offset, int limit);

    // 查询某个会话所包含的私信数量
    int selectLetterCount(String conversationId);

    // 查询未读私信的数量
    int selectLetterUnreadCount(int userId, String conversationId);

}
  • message-mapper.xml




    
        id
        , from_id, to_id, conversation_id, content, status, create_time
    

    
        from_id
        , to_id, conversation_id, content, status, create_time
    

    
    
        select
        
        from message
        where id in (
        select max(id) from message
        where status != 2
        and from_id != 1
        and (from_id = #{userId} or to_id = #{userId})
        group by conversation_id
        )
        order by id desc
        limit #{offset}, #{limit}
    

    
    
        select
        
        from message
        where status != 2
        and from_id != 1
        and conversation_id = #{conversationId}
        order by id desc
        limit #{offset}, #{limit}
    

    
        select count(id)
        from message
        where status = 0
        and from_id != 1
        and to_id = #{userId}
        
            and conversation_id = #{conversationId}
        
    

    
    
    
    

    
    
    
    
    
    
    


业务层
@Service
public class MessageService {

    @Autowired
    private MessageMapper messageMapper;

    // 查询当前用户的会话列表,针对每个会话只返回一条最新的私信
    public List findConversations(int userId, int offset, int limit) {
        return messageMapper.selectConversations(userId, offset, limit);
    }

    // 查询当前用户的会话数量
    public int findConversationCount(int userId) {
        return messageMapper.selectConversationCount(userId);
    }

    // 查询某个会话所包含的私信列表
    public List findLetters(String conversationId, int offset, int limit) {
        return messageMapper.selectLetters(conversationId, offset, limit);
    }

    // 查询某个会话所包含的私信数量
    public int findLetterCount(String conversationId) {
        return messageMapper.selectLetterCount(conversationId);
    }

    // 查询未读私信的数量
    public int findLetterUnreadCount(int userId, String conversationId) {
        return messageMapper.selectLetterUnreadCount(userId, conversationId);
    }

}
控制层
@Controller
public class MessageController {

    @Autowired
    private MessageService messageService;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private UserService userService;

    // 私信列表
    @RequestMapping(path = "/letter/list", method = RequestMethod.GET)
    public String getLetterList(Model model, Page page) {
        User user = hostHolder.getUser();
        // 设置分页信息
        page.setLimit(5);
        page.setPath("/letter/list");
        page.setRows(messageService.findConversationCount(user.getId())); // 会话数量

        // 会话列表
        List conversationList = messageService.findConversations(user.getId(), page.getOffset(), page.getLimit());
        List> conversations = new ArrayList<>();
        if (conversationList != null) {
            for (Message message : conversationList) {
                Map map = new HashMap<>();
                map.put("conversation", message);
                // 当前会话包含几条消息
                map.put("letterCount", messageService.findLetterCount(message.getConversationId()));
                // 当前会话有几条未读消息
                map.put("unreadCount", messageService.findLetterUnreadCount(user.getId(), message.getConversationId()));
                // 对话的头像:
                // 如果当前用户是发送者,那么头像就应该显示接收者的
                // 如果当前用户是接收者,那么头像就应该显示发送者的
                int targetId = user.getId() == message.getFromId() ? message.getToId() : message.getFromId();
                map.put("target", userService.findUserById(targetId));

                conversations.add(map);
            }
        }
        model.addAttribute("conversations", conversations);

        // 查询总的未读消息的数量
        int letterUnreadCount = messageService.findLetterUnreadCount(user.getId(), null);
        model.addAttribute("letterUnreadCount", letterUnreadCount);

        return "/site/letter";
    }

    // 会话内容
    @RequestMapping(path = "/letter/detail/{conversationId}", method = RequestMethod.GET)
    public String getLetterDetail(@PathVariable("conversationId") String conversationId, Page page, Model model) {
        // 设置分页信息
        page.setLimit(5);
        page.setPath("/letter/detail/" + conversationId);
        page.setRows(messageService.findLetterCount(conversationId)); // 某个会话的私信数量

        // 会话所包含的私信列表
        List letterList = messageService.findLetters(conversationId, page.getOffset(), page.getLimit());
        List> letters = new ArrayList<>();
        if (letterList != null) {
            for (Message message : letterList) {
                Map map = new HashMap<>();
                map.put("letter", message);
                map.put("fromUser", userService.findUserById(message.getFromId()));
                letters.add(map);
            }
        }
        model.addAttribute("letters", letters);

        // 查询私信目标
        model.addAttribute("target", getLetterTarget(conversationId));

        return "/site/letter-detail";
    }

    
    private User getLetterTarget(String conversationId) {
        // 数据库表中的conversation_Id,比如111_112
        // 将其拆分成111和112
        String[] ids = conversationId.split("_");
        int id0 = Integer.parseInt(ids[0]);
        int id1 = Integer.parseInt(ids[1]);

        if (hostHolder.getUser().getId() == id0) {
            return userService.findUserById(id1);
        } else {
            return userService.findUserById(id0);
        }
    }

}
发送私信

业务层
  • UserService.java
		// 根据用户名查询用户信息
    public User findUserByName(String username) {
        return userMapper.selectByName(username);
    }
  • MessageService.java
		// 添加消息
    public int addMessage(Message message) {
        // 对消息的特殊字符进行转义
        message.setContent(HtmlUtils.htmlEscape(message.getContent()));
        // 对消息的敏感词进行过滤
        message.setContent(sensitiveFilter.filter(message.getContent()));
        return messageMapper.insertMessage(message);
    }

    // 将消息变成已读状态
    public int readMessage(List ids) {
        return messageMapper.updateStatus(ids, 1); // 1表示已读
    }
控制层
  • MessageController.java
		// 会话内容
    @RequestMapping(path = "/letter/detail/{conversationId}", method = RequestMethod.GET)
    public String getLetterDetail(@PathVariable("conversationId") String conversationId, Page page, Model model) {
        // 设置分页信息
        page.setLimit(5);
        page.setPath("/letter/detail/" + conversationId);
        page.setRows(messageService.findLetterCount(conversationId)); // 某个会话的私信数量

        // 会话所包含的私信列表
        List letterList = messageService.findLetters(conversationId, page.getOffset(), page.getLimit());
        List> letters = new ArrayList<>();
        if (letterList != null) {
            for (Message message : letterList) {
                Map map = new HashMap<>();
                map.put("letter", message);
                map.put("fromUser", userService.findUserById(message.getFromId()));
                letters.add(map);
            }
        }
        model.addAttribute("letters", letters);

        // 查询私信目标
        model.addAttribute("target", getLetterTarget(conversationId));

        // 设置为已读
        List ids = getLetterIds(letterList);
        if (!ids.isEmpty()) {
            messageService.readMessage(ids);
        }

        return "/site/letter-detail";
    }

    // 返回一个会话里面未读的消息id的集合
    private List getLetterIds(List letterList) {
        List ids = new ArrayList<>();
        if (letterList != null) {
            for (Message message : letterList) {
                // 判断当前用户是不是接收者,并且消息处于未读状态
                if (hostHolder.getUser().getId() == message.getToId() && message.getStatus() == 0) {
                    ids.add(message.getId());
                }
            }
        }
        return ids;
    }
统一处理异常

异常处理类
@ControllerAdvice(annotations = Controller.class) // 只扫描带有@Controller注解的bean
public class ExceptionAdvice {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

    @ExceptionHandler({Exception.class}) // 表示处理所有异常
    public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) {
        logger.error("服务器发生异常:" + e.getMessage());
        for (StackTraceElement element : e.getStackTrace()) {
            logger.error(element.toString());
        }

        // 判断是普通请求还是异步请求
        String xRequestedWith = request.getHeader("x-requested-with");
        // 说明是一个异步请求,发生异常需要返回json格式的字符串
        if ("XMLHttpRequest".equals(xRequestedWith)) {
            response.setContentType("application/plain;charset=UTF-8");
            try {
                PrintWriter writer = response.getWriter();
                writer.write(CommunityUtil.getJSONString(1, "服务器异常!"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } else { // 普通请求的异常就直接返回错误页面
            try {
                response.sendRedirect(request.getContextPath() + "/error");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

}
错误页面
  • 错误页面需要放在error包下

控制层
  • 控制层需要增加跳转到错误页面的方法
		// 跳转到500错误页面
    @RequestMapping(path = "/error", method = RequestMethod.GET)
    public String getErrorPage() {
        return "/error/500";
    }
统一记录日志

@Component
@Aspect
public class ServiceLogAspect {

    private static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class);

    @Pointcut("execution(* com.nowcoder.community.service.*.*(..))")
    public void pointcut() {

    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        // 用户[ip地址],在[xxx时间] 访问了 [com.nowcoder.community.service.xxx()]
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String ip = request.getRemoteHost();
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        // com.nowcoder.community.service.xxx()
        String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        logger.info(String.format("用户[%s], 在[%s], 访问了[%s]", ip, now, target));
    }

}

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/957063.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号