一、为什么用webscocket

http只能客户端发向服务器,而我们需要双向通信

二、先导包

<!--WebSocket 依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-messaging</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--处理时间格式的 -->
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.8.2</version>
    </dependency>
    <dependency>
      <groupId>javax.websocket</groupId>
      <artifactId>javax.websocket-api</artifactId>
      <version>1.0</version>
      <scope>provided</scope>
    </dependency>
<!--如果客户端浏览器不支持websocket降级为aspectj -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.1</version>
    </dependency>

三、配置需要websocket拦截的路径

可以配置xml,可以用注解在类中配置(注意添加context:component-scan 扫到这个类)我这里是注解

@EnableWebMvc
@Configuration
@EnableWebSocket
public class MyWebSocketConfig  implements WebSocketConfigurer {
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        webSocketHandlerRegistry.addHandler(webSocketHandler(),"/websocket/socketServer.action")
                .addInterceptors(new MyHandShakeInterceptor());
        webSocketHandlerRegistry.addHandler(webSocketHandler(), "/sockjs/socketServer.action").setAllowedOrigins("http://localhost:8080")
                .addInterceptors(new MyHandShakeInterceptor()).withSockJS();
    }
    @Bean
    public MyWebSocketHandler webSocketHandler(){
        return new MyWebSocketHandler();
    }
}

这里路径就是JavaScript里ws://…(后面有),如果你springmvc配的要带.action,这里就要带.action,JavaScript里和这长得一样,也带.action。如果你配的.do就加.do。
配的/就不加

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>

四、配置握手前的拦截器

这里不用粘过去,手打前面,alt+enter会生成这俩函数,函数里完成握手前的操做。
应该把你当前登录的用户存到map里,我这里代码比较臭是因为我有两种用户,得分别判断。

import java.util.Map;

public class MyHandShakeInterceptor implements HandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
        ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) serverHttpRequest;
        HttpSession session = servletRequest.getServletRequest().getSession(false);
        //标记用户
        //如果是user
        if (session.getAttribute("wUsers")!=null) {
            System.out.println("Websocket:求职者[username:" + ((ServletServerHttpRequest) serverHttpRequest).getServletRequest().getSession(false).getAttribute("wUsers") + "]已经建立连接");
            WUsers user = (WUsers) session.getAttribute("wUsers");
            if(user!=null){
                map.put("uid", user.getUsername());//为服务器创建WebSocketSession做准备
                System.out.println("用户username:"+user.getUsername()+" 被加入");
            }else{
                System.out.println("user为空");
                return false;
            }
        }
        //如果是hr
        if (session.getAttribute("wHr")!=null) {
            System.out.println("Websocket:招聘者[username:" + ((ServletServerHttpRequest) serverHttpRequest).getServletRequest().getSession(false).getAttribute("wUsers") + "]已经建立连接");
            WHr user = (WHr) session.getAttribute("wHr");
            if(user!=null){
                map.put("uid", user.getUsername());//为服务器创建WebSocketSession做准备
                System.out.println("用户username:"+user.getUsername()+" 被加入");
            }else{
                System.out.println("user为空");
                return false;
            }
        }
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {

    }
}

五、配置发消息的处理器

还是建议手打,再生成,不要直接粘我下面的代码,可能会出问题

注意:我的主键是String型的usernmae,代码里写的uid
Message是自定义的类,属性最好有fromid,toid,text,time,其他的随意加

import java.util.Map;

@Component
public class MyWebSocketHandler extends TextWebSocketHandler {



    @Autowired
    private ContactService youandmeService;

    //当MyWebSocketHandler类被加载时就会创建该Map,随类而生
    public static final Map<String, WebSocketSession> userSocketSessionMap;

    static {
        userSocketSessionMap = new HashMap<String, WebSocketSession>();
    }
    public MyWebSocketHandler() {}

    //握手实现连接后,也就是MyHandShakeInterceptor beforeHandshake 出来
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        //beforeHandshake中 map放进去的
        String uid = (String) webSocketSession.getAttributes().get("uid");
//        System.out.println("握手连接uid:"+uid);
        if (userSocketSessionMap.get(uid) == null) {
            userSocketSessionMap.put(uid, webSocketSession);
        }

    }
    //发送信息
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
        System.out.println("进handleMessage");
        if(webSocketMessage.getPayloadLength()==0)return;
        //得到Socket通道中的数据并转化为Message对象
        Message msg=new Gson().fromJson(webSocketMessage.getPayload().toString(),Message.class);

        Timestamp now = new Timestamp(System.currentTimeMillis());
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        msg.setMessagedate(sdf.format(now));
//        System.out.println(msg);
        //将信息保存至数据库
        youandmeService.addMessage(msg);
        //发送Socket信息
        sendMessageToUser(msg.getToid(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg)));
    }

    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {

    }

    /**
     * 在此刷新页面就相当于断开WebSocket连接,原本在静态变量userSocketSessionMap中的
     * WebSocketSession会变成关闭状态(close),但是刷新后的第二次连接服务器创建的
     * 新WebSocketSession(open状态)又不会加入到userSocketSessionMap中,所以这样就无法发送消息
     * 因此应当在关闭连接这个切面增加去除userSocketSessionMap中当前处于close状态的WebSocketSession,
     * 让新创建的WebSocketSession(open状态)可以加入到userSocketSessionMap中
     * @param webSocketSession
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
//        System.out.println("WebSocket:"+webSocketSession.getAttributes().get("uid")+"close connection");
        Iterator<Map.Entry<String,WebSocketSession>> iterator = userSocketSessionMap.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<String,WebSocketSession> entry = iterator.next();
            if(entry.getValue().getAttributes().get("uid")==webSocketSession.getAttributes().get("uid")){
                userSocketSessionMap.remove(webSocketSession.getAttributes().get("uid"));
//                System.out.println("WebSocket in staticMap:" + webSocketSession.getAttributes().get("uid") + "removed");
            }
        }

    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    //发送信息的实现
    public void sendMessageToUser(String username, TextMessage message)
            throws IOException {

        WebSocketSession session = userSocketSessionMap.get(username);
        if (session != null && session.isOpen()) {
            session.sendMessage(message);
        }
    }
}

六、配置前端jsp

必须有的
注意:这里的ws地址跟controller的地址差不多,你要配了.action(或.do)就得加

下面的send()函数,是我点击发送触发的函数,一旦有消息来,自动执行websocket.onmessage

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

//这是我本地的,需要自己下
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>

<script>
        var socketPath = "${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/";
        var websocket = null;
        if ('WebSocket' in window) {
            websocket = new WebSocket("ws://"+socketPath+"websocket/socketServer.action");
        }
        else if ('MozWebSocket' in window) {
            alert(2);
            websocket = new MozWebSocket("ws://"+socketPath+"websocket/socketServer.action");
        }
        else {
            alert(3);
            websocket = new SockJS("ws://"+socketPath+"sockjs/socketServer.action");
        }
        websocket.onopen = onOpen;
        websocket.onmessage = onMessage;
        websocket.onerror = onError;
        websocket.onclose = onClose;

        function onOpen(event) {
            console.log("连接成功");
            console.log(event);
        }

        function onMessage(even) {
            var obj = JSON.parse(even.data);
            if (obj.fromid=="${who.username}"){
                $("#jia").append("<li>"+
                          "<div class=\"message-data\">"+
                              "<span class=\"message-data-name\"><i class=\"fa fa-circle online\"></i>${who.name}</span>"+
                              "<span class=\"message-data-time\">"+ obj.messagedate+"</span>"+
                          "</div>"+
                          "<div class=\"message my-message\">"+
                    obj.messagetext+
                          "</div>"+
                      "</li>");
            }
        }
        function onError(event) {
            console.log("连接失败");
            console.log(event);
        }
        function onClose(event) {
            console.log("Socket连接断开");
            console.log(event);
        }
        function send(me,you){
            var data = {};//新建data对象,并规定属性名与相应的值
            data['fromid'] = me;
            data['toid'] = you;
            if ("${wHr}"== "") {
                data['fromname'] = "${wUsers.name}";
            }
            if ("${wUsers}"== "") {
                data['fromname'] = "${wHr.name}";
            }
            data['toname'] = "${who.name}";
            data['messagetext'] = $("#message-to-send").val();
            // alert("发送");
            var now = new Date();
            var yyyyhh = now.toLocaleDateString().replace(/\//g, "-") + " " + now.toTimeString().substr(0, 8);
            if (websocket.readyState === websocket.OPEN) {
                websocket.send(JSON.stringify(data));//调用后台handleTextMessage方法
                //给别人发,自己这也得更新
                $("#jia").append("<li class='clearfix'>"+
                    "<div class=\"message-data align-right\">"+
                    "<span class=\"message-data-name\"><i class=\"fa fa-circle me\"></i>"+data.toname+"</span>"+
                    "<span class=\"message-data-time\">"+ yyyyhh+"</span>"+
                    "</div>"+
                    "<div class=\"message other-message float-right\">"+
                    data.messagetext+
                    "</div>"+
                    "</li>");
                document.getElementById("messagediv").scrollTop = document.getElementById("messagediv").scrollHeight;
            } else {
                alert("连接失败!");
            }
        }
    </script>

七、完整的前端代码

这里我是东拼西凑的 , header-end 之后是对话框主体
${usernameset}是我进这个页面前在controller里session.setAttribute的发过消息的用户名表
${user}是当前登录的用户的用户名
${who}是点击用户名之后,对应的联系人的对象
${list}是点击用户名之后,进入controller,查询与这个人的聊天记录,再回来显示的聊天记录。

我这里用的window.location,其实应该用异步ajax,回来之后再重新刷新聊天框。但我后台里存上request,前端一取就是null,只有这个页面这样,有没有大佬能解释下。ajax版的在后面我注释掉了

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <script type="text/javascript">
        if ("${msg}" != "") {
            alert("${msg}");
        }
    </script>
    <c:remove var="msg"></c:remove>
    <title>基于智能推荐的求职招聘系统</title>
    <!-- Favicon -->
    <link rel="icon" href="${pageContext.request.contextPath}/assets/images/favicon.png" type="image/png" sizes="32x32">
    <!-- All CSS -->
    <link rel="stylesheet" href="https://www.jq22.com/jquery/bootstrap-4.2.1.css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/aos.min.css">
    <link rel="stylesheet" href="https://www.jq22.com/jquery/font-awesome.4.7.0.css">
    <script src="https://kit.fontawesome.com/b723086348.js" crossorigin="anonymous"></script>

    <script type="text/javascript" src="http://cdn.bootcss.com/sockjs-client/1.1.1/sockjs.js"></script>
    <script>
        var socketPath = "${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/";
        // var webSocket = new WebSocket("ws://"+socketPath+"websocket/socketServer.action");
        var websocket = null;
        if ('WebSocket' in window) {
            websocket = new WebSocket("ws://"+socketPath+"websocket/socketServer.action");
        }
        else if ('MozWebSocket' in window) {
            alert(2);
            websocket = new MozWebSocket("ws://"+socketPath+"websocket/socketServer.action");
        }
        else {
            alert(3);
            websocket = new SockJS("ws://"+socketPath+"sockjs/socketServer.action");
        }
        websocket.onopen = onOpen;
        websocket.onmessage = onMessage;
        websocket.onerror = onError;
        websocket.onclose = onClose;

        function onOpen(event) {
            console.log("连接成功");
            console.log(event);
        }

        function onMessage(even) {
            var obj = JSON.parse(even.data);
            <%--alert(obj.fromid);--%>
            <%--alert("${who.username}");--%>
            if (obj.fromid=="${who.username}"){
                // alert("要刷");
                <%--window.location="${pageContext.request.contextPath}/showmessage/showmessage1.action?your=${who.username}";--%>
                $("#jia").append("<li>"+
                          "<div class=\"message-data\">"+
                              "<span class=\"message-data-name\"><i class=\"fa fa-circle online\"></i>${who.name}</span>"+
                              "<span class=\"message-data-time\">"+ obj.messagedate+"</span>"+
                          "</div>"+
                          "<div class=\"message my-message\">"+
                    obj.messagetext+
                          "</div>"+
                      "</li>");
            }
        }
        function onError(event) {
            console.log("连接失败");
            console.log(event);
        }
        function onClose(event) {
            console.log("Socket连接断开");
            console.log(event);
        }
        function send(me,you){
            var data = {};//新建data对象,并规定属性名与相应的值
            <%--if ("${wUsers}"!== "") {--%>
            <%--    data['fromid'] =${wUsers.username};--%>
            <%--    data['fromname'] = ${wUsers.name};--%>
            <%--}--%>
            <%--if ("${wHr}"!== "") {--%>
            <%--    data['fromid'] =${wHr.username};--%>
            <%--    data['fromname'] = ${wHr.name};--%>
            <%--}--%>
            data['fromid'] = me;
            data['toid'] = you;
            if ("${wHr}"== "") {
                data['fromname'] = "${wUsers.name}";
            }
            if ("${wUsers}"== "") {
                data['fromname'] = "${wHr.name}";
            }
            data['toname'] = "${who.name}";
            data['messagetext'] = $("#message-to-send").val();
            // alert("发送");
            var now = new Date();
            var yyyyhh = now.toLocaleDateString().replace(/\//g, "-") + " " + now.toTimeString().substr(0, 8);
            if (websocket.readyState === websocket.OPEN) {
                websocket.send(JSON.stringify(data));//调用后台handleTextMessage方法
                $("#jia").append("<li class='clearfix'>"+
                    "<div class=\"message-data align-right\">"+
                    "<span class=\"message-data-name\"><i class=\"fa fa-circle me\"></i>"+data.toname+"</span>"+
                    "<span class=\"message-data-time\">"+ yyyyhh+"</span>"+
                    "</div>"+
                    "<div class=\"message other-message float-right\">"+
                    data.messagetext+
                    "</div>"+
                    "</li>");
                document.getElementById("messagediv").scrollTop = document.getElementById("messagediv").scrollHeight;
            } else {
                alert("连接失败!");
            }
        }
    </script>

    <link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/magnific.min.css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/owl.carousel.min.css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/select2.min.css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/slimmenu.min.css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/assets/css/style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/dist/style.css">
    <!-- Google font -->
    <link href="https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700" rel="stylesheet">

    <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
</head>
   <body>
      <!--header-start -->
    <header class="header-area sticky">
        <div class="container">
            <div class="row">
                <div class="col-lg-2">
                    <div class="logo">
                        <a href="${pageContext.request.contextPath}/usershowinfo/splitone.action"><img src="${pageContext.request.contextPath}/assets/images/logo.png" alt="image" /></a>
                    </div>
                </div>
                <div class="col-lg-10">
                    <div class="header-container d-flex justify-content-between highlight">
                        <nav class="highlight">
                            <ul id="responsive-menu" class="slimmenu">
                                <li class="nav-item"><a class="nav-link" href="${pageContext.request.contextPath}/usershowinfo/splitone.action">主页</a>
                                <li id="userlist" class="nav-item">
                                    <a class="nav-link" href="#">我的</a>
                                    <ul>
                                        <li><a href="${pageContext.request.contextPath}/toView/user/addinfo.action">消息</a>
                                        <li><a onclick="logoff()" href="">退出登录</a>
                                    </ul>
                                <li id="hrlist" class="nav-item">
                                    <a class="nav-link" href="#">我的</a>
                                    <ul>
                                        <li><a href="${pageContext.request.contextPath}/toView/user/addinfo.action">新增招聘信息</a>
                                        <li><a href="${pageContext.request.contextPath}/toView/user/addinfo.action">管理招聘信息</a>
                                        <li><a href="${pageContext.request.contextPath}/toView/user/addinfo.action">消息</a>
                                        <li><a onclick="logoff()" href="">退出登录</a>
                                    </ul>
                                <li id="login" class="nav-item call-to-action"><a href="${pageContext.request.contextPath}/userlogin.jsp">登录</a>
                            </ul>
                        </nav>
                    </div>
                </div>
            </div>
        </div>
    </header>
    <!--header-end -->
      <!-- partial:index.partial.html -->
      <div class="container1 clearfix">
          <div class="people-list" id="people-list">
              <div class="search">
                  <input type="text" placeholder="search" />
                  <i class="fa fa-search"></i>
              </div>
              <ul class="list">
                <c:choose>
                    <c:when test="${usernameset.size()!=0}">
                        <c:forEach items="${usernameset}" var="p">
                            <li class="clearfix" >
                                <a style="display: block;" href="javascript:show('${p}')" >
                                <img src="/img/t1.png" alt="avatar" />
                                <div class="about">
                                    <div class="name">${p}</div>
                                    <div class="status">
                                        <i class="fa fa-circle online"></i>
                                    </div>
                                </div>
                                </a>
                            </li>
                        </c:forEach>
                    </c:when>
                    <c:otherwise>
                        <li class="clearfix">
                            <img src="/img/t1.png" alt="avatar" />
                            <div class="about">
                                <div class="name">Vincent Porter</div>
                                <div class="status">
                                    <i class="fa fa-circle online"></i> online
                                </div>
                            </div>
                        </li>
                        <li class="clearfix">
                            <img src="/img/t2.png" alt="avatar" />
                            <div class="about">
                                <div class="name">Aiden Chavez</div>
                                <div class="status">
                                    <i class="fa fa-circle offline"></i> left 7 mins ago
                                </div>
                            </div>
                        </li>
                    </c:otherwise>
                </c:choose>
              </ul>
          </div>

          <div class="chat">
                  
              <div class="chat-header clearfix">
                  <img src="/img/t1.png" alt="avatar" />

                  <div class="chat-about">
                      <div class="chat-with" >${who.name}</div>
                      <div class="chat-num-messages"></div>
                  </div>
                  <i class="fa fa-star"></i>
              </div> <!-- end chat-header -->
              <div class="chat-history" id="messagediv">
                  <c:choose>
                      <c:when test="${list.size()!=0}">
                  <ul id="jia">
                      <c:forEach items="${list}" var="p">
                          <c:if test="${p.fromid == user}">
                      <li class="clearfix">
                          <div class="message-data align-right">
                              <span class="message-data-time" >${p.messagedate}</span> &nbsp; &nbsp;
                              <span class="message-data-name" >${p.fromname}</span> <i class="fa fa-circle me"></i>

                          </div>
                          <div class="message other-message float-right">
                              ${p.messagetext}
                          </div>
                      </li>
                          </c:if>
                          <c:if test="${p.toid == user}">
                      <li>
                          <div class="message-data">
                              <span class="message-data-name"><i class="fa fa-circle online"></i>${p.fromname}</span>
                              <span class="message-data-time">${p.messagedate}</span>
                          </div>
                          <div class="message my-message">
                              ${p.messagetext}
                          </div>
                      </li>
                        </c:if>
                      </c:forEach>

                  </ul>
                     </c:when>
                      <c:otherwise>没有信息</c:otherwise>
                  </c:choose>
              </div> <!-- end chat-history -->
              <div class="chat-message clearfix">
                  <textarea name="message-to-send" id="message-to-send" placeholder ="Type your message" rows="3"></textarea>

                  <i class="fa fa-file-o"></i> &nbsp;&nbsp;&nbsp;
                  <i class="fa fa-file-image-o"></i>

                  <button onclick="send('${user}','${who.username}')">发送</button>

              </div> <!-- end chat-message -->

          </div> <!-- end chat -->

      </div> <!-- end container -->
      
<%--      <script id="message-template" type="text/x-handlebars-template">--%>
<%--          <li class="clearfix">--%>
<%--              <div class="message-data align-right">--%>
<%--                  <span class="message-data-time" >{{time}}, Today</span> &nbsp; &nbsp;--%>
<%--                  <span class="message-data-name" >Olia</span> <i class="fa fa-circle me"></i>--%>
<%--              </div>--%>
<%--              <div class="message other-message float-right">--%>
<%--                  {{messageOutput}}--%>
<%--              </div>--%>
<%--          </li>--%>
<%--      </script>--%>

<%--      <script id="message-response-template" type="text/x-handlebars-template">--%>
<%--          <li>--%>
<%--              <div class="message-data">--%>
<%--                  <span class="message-data-name"><i class="fa fa-circle online"></i> Vincent</span>--%>
<%--                  <span class="message-data-time">{{time}}, Today</span>--%>
<%--              </div>--%>
<%--              <div class="message my-message">--%>
<%--                  {{response}}--%>
<%--              </div>--%>
<%--          </li>--%>
<%--      </script>--%>
      <!--footer-area-start -->
      <footer>
          <div class="footer-area pt-100 pb-100 clearfix minus-30">
              <div class="container">
                  <div class="row">
                      <div class="col-lg-3 col-md-3 col-sm-6">
                          <div class="footer-widget">
                              <div class="widget-title">
                                  <a href="${pageContext.request.contextPath}/toVeiw/user/index.action"><img src="${pageContext.request.contextPath}/assets/images/footer-logo.png" alt="image" /></a>
                              </div>
                              <p>Cras semper auctor neque vitae tempus quam pellentesque nec nam aliquam sem et tortor consequat id porta nibh venenatis cras sed felis eget </p>
                              <div class="social-link mt-4">
                                  <ul>
                                      <li class="facebook"><a href="#"><i class="fa fa-facebook-f"></i></a></li>
                                      <li class="twitter"><a href="#"><i class="fa fa-twitter"></i></a></li>

                                      <li class="linkedin"><a href="#"><i class="fa fa-linkedin" ></i></a></li>
                                  </ul>
                              </div>
                          </div>
                      </div>
                      <div class="col-lg-3 col-md-3 col-sm-6">
                          <div class="footer-widget">
                              <div class="widget-title">
                                  <h3>Candidates</h3>
                              </div>
                              <div class="widget-link">
                                  <ul>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>Browse Jobs</a></li>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>Submit Resume</a></li>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>My Bookmarks</a></li>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>Job Alerts</a></li>
                                  </ul>
                              </div>
                          </div>
                      </div>
                      <div class="col-lg-3 col-md-3 col-sm-6">
                          <div class="footer-widget">
                              <div class="widget-title">
                                  <h3>Employers</h3>
                              </div>
                              <div class="widget-link">
                                  <ul>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>Employers</a></li>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>Add Job</a></li>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>Jobs Listing</a></li>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>Employers Grid</a></li>
                                      <li><a href="#"><i class="fa fa-angle-right" aria-hidden="true"></i>Employer Listing</a></li>
                                  </ul>
                              </div>
                          </div>
                      </div>
                      <div class="col-lg-3 col-md-3 col-sm-6">
                          <div class="footer-widget">
                              <div class="widget-title">
                                  <h3>Subscribe Us</h3>
                              </div>
                              <div class="widget-text">
                                  <form action="#">
                                      <input type="email" placeholder="Your Email" />
                                      <button type="submit" class="buttonfx curtainup">Subscribe</button>
                                  </form>
                                  <p>Nceptos, nulla dictumst neque nam aliquam</p>
                              </div>
                          </div>
                      </div>
                  </div>
              </div>
          </div>
          <div class="footer-bottom-area clearfix">
              <div class="container">
                  <div class="row">
                      <div class="col-md-12">
                          <div class="footer-bottom text-center">
                              <p>&copy; Copyright - 2022 hrh - Designed By <a href="http://www.baidu.com/">胡荣华</a></p>
                          </div>
                      </div>
                  </div>
              </div>
          </div>
      </footer>
      <!--footer-area-end -->
      <!-- ====================ALL JS FILE HERE===================================== -->
      <!-- jQuery -->
	  <script src="${pageContext.request.contextPath}/assets/js/modules/bootstrap.min.js"></script>
	  <script src="${pageContext.request.contextPath}/assets/js/modules/proper.js"></script>
	  <script src="${pageContext.request.contextPath}/assets/js/modules/jquery.waypoints.min.js"></script>
	  <script src="${pageContext.request.contextPath}/assets/js/modules/owl.carousel.min.js"></script>
	  <script src="${pageContext.request.contextPath}/assets/js/modules/magnific.min.js"></script>
	  <script src="${pageContext.request.contextPath}/assets/js/modules/typing.min.js"></script>
	  <script src="${pageContext.request.contextPath}/assets/js/modules/select2.min.js"></script>
	  <script src="${pageContext.request.contextPath}/assets/js/modules/aos.min.js"></script>
	  <script src="${pageContext.request.contextPath}/assets/js/modules/slimmenu.min.js"></script>
<%--      <script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>--%>
      <script src='${pageContext.request.contextPath}/dist/handlebars.min.js'></script>
      <script src='${pageContext.request.contextPath}/dist/list.min.js'></script>
      <script  src="${pageContext.request.contextPath}/dist/script.js"></script>
      <script src="${pageContext.request.contextPath}/assets/js/app.js"></script>

   </body>
<script type="text/javascript">
    <%--function showmessage(your){--%>
    <%--    $.ajax({--%>
    <%--        url:"${pageContext.request.contextPath}/showmessage/showmessage1.action",--%>
    <%--        data:{'your':your},--%>
    <%--        type :"post",--%>
    <%--        success:function (){--%>
    <%--            alert("哈");--%>
    <%--            alert("${list.size()}")--%>
    <%--            $("#messagediv").load("${pageContext.request.contextPath}/user/contact.action  #messagediv");--%>
    <%--        }--%>
    <%--        })--%>
    <%--}--%>
</script>
<script>
    function show(username){
        window.location="${pageContext.request.contextPath}/showmessage/showmessage1.action?your="+username;
    }

    if ("${wHr}"== ""){
        document.getElementById("hrlist").style.display="none";
    }
    if ("${wUsers}"== ""){
        document.getElementById("userlist").style.display="none";
    }
    if ("${wHr}"!= ""||"${wUsers}"!= ""){
        document.getElementById("login").style.display="none";
    }
    function logoff(){
        $.ajax({
            type:"post",
            url:"${pageContext.request.contextPath}/user/logoff.action",
            async : false,
            success:function (){
                alert("退出登录成功");
                location.href="${pageContext.request.contextPath}/userlogin.jsp";
            }
        })

    }
</script>
</html>

八、对话框运行展示

因为是东拼西凑的,我一点也不懂前端,所以这个上面总是挡
在这里插入图片描述

九、其他问题

像编写controller,service,pojo(entity),mapper这些问题就不再赘述了。

再多说一个:message按时间升序取,数据库新手不建议用Timestamp,用varchar就行了

希望有大佬能帮我解答:ajax异步跳controller,controller里sission存东西,回ajax取不出(之前存的都在,就是新存的el表达式一取就是null)

参考博客:
http://t.csdn.cn/ejJeI
http://t.csdn.cn/kJ8Bl