使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台

大二学生党一枚,这两个月一直在写一个用structs2框架实现微信二次开发的web程序,前几天将这个程序写完之后,在此沉淀一下。有不准确的地方希望大家指出。
在介绍之前先发送传送门:
由于所有的学习资源来自于google,所以就把干货也链过来了,希望以下各位博主支持。
gitlab代码传送http://mukever.online/root/kaowu
javaweb学习记录http://www.cnblogs.com/xdp-gacl/p/3760336.html
structs2拦截器http://blog.csdn.net/kiss_vicente/article/details/7597700
柳峰的微信开发教程http://blog.csdn.net/lyq8479/article/details/8937622
微信开发文档http://mp.weixin.qq.com/wiki/home/
git使用(多人协作)http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/

系统实现的功能是:

  1. 实现后台学院监考安排。
  2. 用户分为普通教师用户,管理员用户,超级管理员,三级权限。
  3. 将信息实时推送到安排监考的教师的微信手机端。
  4. 教师可以在微信手机端实时查看自己的相关监考信息。
  5. 扫描微信二维码后,需要管理员审核通过后才可以使用相关功能。

介绍一下整个架构
使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台_第1张图片

微信用户通过关注微信公众号,可以实现跟系统web通信,(学院管理员通过审核通过后才能使用相关的功能,否则会友情提示)。
微信开发步骤:
1.获得接口权限
在调用接口前,微信会通过get方式向你的服务器发送几个字符串参数,可以根据开发文档提示,得到这几个参数,使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台_第2张图片
(如果加密之后还需要对数据解密得到)然后向微信服务器原样返回echostr参数内容,就能完成接口的调用。
2.保存accesstoken
每次调用接口时需要验证accesstoken是否有效,我的做法是将其存入数据库,下次需要时直接将其拿出,并比对时间戳,如果失效则重新获取accesstoken。

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import com.db.kaowu.sau.www.DBUnit;
import com.pojo.wechat.kaowu.sau.www.AccessToken;

/**
 * 保持token长期有效
 *
 */
public class GetExistAccessToken implements AppId {

    // 将AccessToken写进数据库
    public static AccessToken getToken() {

        Connection connection = null;
        AccessToken token = new AccessToken();
        connection = DBUnit.getConn();
        String query_sql = "select * from db_accesstoken";
        String delete_sql = "delete from db_accesstoken";
        String insert_sql = "";
        Date nowdate = new Date();
        String dateformdb = "";
        try {

            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(query_sql);
            // 当数据库中有数据时
            if (resultSet.next()) {
                dateformdb = resultSet.getString(3);
                // 判断数据库中的数据是否有效 为了保存数据的有效性 将token的有效期缩短50秒
                if (nowdate.getTime() - Long.parseLong(dateformdb) <= 7150000) {
                    // System.out.println("数据库");
                    token.setToken(resultSet.getString(2));
                    token.setExpiresIn(7200);
                } else {
                    // 数据库中的token失效了
                    // 调用接口获取access_token
                    // System.out.println("获取");
                    AccessToken at = WeixinUtil.getAccessToken(appId, appSecret);
                    // 删除原有token
                    statement.executeUpdate(delete_sql);
                    // 拼接inset_sql
                    insert_sql = "insert into db_accesstoken (token, date) values('" + at.getToken() + "' ,'"
                            + nowdate.getTime() + "')";
                    // 跟新token
                    statement.executeUpdate(insert_sql);
                    // 返回的token
                    token = at;
                }
            } else {
                // 数据库没有数据时肯定直接从微信服务器获取 然后存入数据库

                // 调用接口获取access_token
                AccessToken at = WeixinUtil.getAccessToken(appId, appSecret);
                // 拼接inset_sql
                insert_sql = "insert into db_accesstoken (token, date) values('" + at.getToken() + "' ,'"
                        + nowdate.getTime() + "')";
                // 跟新token
                // System.out.println("获取");
                statement.executeUpdate(insert_sql);
                // 返回的token
                token = at;

            }
            // 关闭数据库连接
            closeConnection(connection);
        } catch (SQLException e) {
            e.printStackTrace();
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return token;
    }

    // 关闭数据库连接
    public static void closeConnection(Connection connection) throws SQLException {

        connection.close();
    }

}
这样能保证每次就不用从微信服务器那获取accesstoken,

3.微信接口的调用
在柳峰的博客中写的已经很详细了,他把所需要解析的各种信息基类都做了封装,我们完全可以利用嘛(没必要造重复的轮子)
4.微信开发中需要注意的问题:
1)接口权限问题,由于普通公众号没有高级权限,可以通过使用微信测试账号开发。
2)自己的服务器跟微信服务器是通过json数据传输。
3)在拦截请求时,需要放过处理微信服务器发送的请求。
4)手机端跟微信交互的时候 ,后台报错时,手机端的微信会提示无法响应。(正常情况下,服务器都会在5秒处理完请求)
5)不管是php还是java,开发的思路都是一样的。

后台开发步骤
1.数据库设计:
使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台_第3张图片
2.前台页面与后台交互
前台页面通过js+jquery+ajax跟后台通过传递json数据做交互
3.action配置



<struts>
    <package name="struts" namespace="/" extends="struts-default,json-default">
        <interceptors>
            
            <interceptor name="permission" class="com.filter.kaowu.sau.www.SessionIterceptor" />
            
            <interceptor-stack name="permissionStack">
                 <interceptor-ref name="defaultStack" />
                <interceptor-ref name="permission" />
            interceptor-stack>
        interceptors>
        
        <default-interceptor-ref name="permissionStack" />
        
        <global-results>
            <result name="nologin"  type="redirect">/login.htmlresult>
        global-results>


        
        <action name="Login" class="com.action.kaowu.sau.www.Login">
            <result name = "success"  type="json">
                <param name="root">resultparam>
            result>
            <result name="input">/login.htmlresult>  
        action>

        
        <action name="Sign_*" class="com.action.kaowu.sau.www.Sign" method="{1}">
            <result name="success">/idnex.htmlresult>
            <result type="json">
                <param name="root">resultparam>
            result>

        action>
        
        <action name="WeChat_*" class="com.action.kaowu.sau.www.WeChat" method="{1}">

        action>


        
        <action name="Register" class="com.action.kaowu.sau.www.Register">
             <result name = "success"  type="json">
                <param name="root">resultparam>
             result>

        action>


        
        <action name="AuditUser" class="com.action.kaowu.sau.www.AuditUser">
             <result name = "success"  type="json">
                <param name="root">resultparam>
             result>

        action>


        
        <action name="Audit" class="com.action.kaowu.sau.www.Audit">
             <result name = "success"  type="json">
                <param name="root">resultparam>
             result>

        action>

        
        <action name="UserInfo" class="com.action.kaowu.sau.www.UserInfo">
             <result name = "success"  type="json">
                <param name="root">resultparam>
             result>

        action>

        
        <action name="Grade_*" class="com.action.kaowu.sau.www.Grade" method="{1}">
            
             <result name="add" type="json">
                <param name="root">resultparam>
             result>
             
             <result name="delete" type="json">
                <param name="root">resultparam>
             result>
             
             <result name="getList" type="json">
                <param name="root">resultparam>
             result>


        action>


        
        <action name="ClassRoom_*" class="com.action.kaowu.sau.www.ClassRoom" method="{1}">
            
             <result name="add" type="json">
                <param name="root">resultparam>
             result>
             
             <result name="delete" type="json">
                <param name="root">resultparam>
             result>

             
             <result name="getList" type="json">
                <param name="root">resultparam>
             result>
             
             <result name="update" type="json">
                <param name="root">resultparam>
             result>

        action>

        
        <action name="NotUseRoom" class="com.action.kaowu.sau.www.NotUseRoom">
            <result name="success" type="json">
                <param name="root">resultparam>
             result>

        action>
        
        <action name="CreateNewTest" class="com.action.kaowu.sau.www.CreateNewTest">
            <result name="success" type="json">
                <param name="root">resultparam>
             result>

        action>    
         
        <action name="NotUseTher" class="com.action.kaowu.sau.www.NotUseTher">
            <result name="success" type="json">
                <param name="root">resultparam>
             result>

        action>
        
        <action name="AffirmTest" class="com.action.kaowu.sau.www.AffirmTest">
            <result name="success" type="json">
                <param name="root">resultparam>
             result>

        action> 

        
        <action name="TestList_*" class="com.action.kaowu.sau.www.TestList" method="{1}">
            
            <result name = "getlist"  type="json">
                <param name="root">resultparam>
            result>
            <result name = "delete"  type="json">
                <param name="root">statusparam>
            result>
        action>

        
        <action name="Admin_*" class="com.action.kaowu.sau.www.Admin" method="{1}">
            <result name="updata" type="json">
                <param name="root">resultparam>
            result>
            <result name="add" type="json">
                <param name="root">resultparam>
            result>
            <result name="delete" type="json">
                <param name="root">resultparam>
            result>
            <result name="list" type="json">
                <param name="root">resultparam>
            result>
        action>

        
        <action name="UserInfoupdata" class="com.action.kaowu.sau.www.UserInfoupdata">
            <result name="updata" type="json">
                <param name="root">resultparam>
            result>
        action>
        
        <action name="UserTest" class="com.action.kaowu.sau.www.UserTest">
            <result name="success" type="json">
                <param name="root">resultparam>
            result>
        action>


        
        <action name="Quit" class="com.action.kaowu.sau.www.Quit">
            <result name="success">/login.html
            result>  
        action>
    package>

4.jdbc连接数据库
1)将用户名和密码写在web.xml文件里面

package com.db.kaowu.sau.www;

import java.sql.*;

import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;

/*
 * 
 * 数据库连接对象
 */
public class DBUnit {

    // 返回数据库连接对象
    public static Connection getConn() {

        ServletContext context = ServletActionContext.getServletContext();
        // 连接数据库
        String url = context.getInitParameter("url");
        String username = context.getInitParameter("username");
        String psd = context.getInitParameter("password");

        String jdbcName = context.getInitParameter("driver");

        Connection conn = null;
        try {
            Class.forName(jdbcName);
            // System.out.println("驱动加载成功!");
        } catch (Exception e) {
        }
        try {
            // 本地连接
            // conn=DriverManager.getConnection(url);

            // 服务器连接
            conn = DriverManager.getConnection(url, username, psd);

        } catch (SQLException ex) {
        }
        return conn;
    }

}

5.web.xml文件配置


<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <filter>
    <filter-name>struts2filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>
  filter>
  <filter-mapping>
    <filter-name>struts2filter-name>
    <url-pattern>*.actionurl-pattern>
  filter-mapping>
  <welcome-file-list>
    <welcome-file>/login.htmlwelcome-file>
  welcome-file-list>
  
   <session-config>
     <session-timeout>30session-timeout>
   session-config> 

  
  <context-param>
       <param-name>appIdparam-name>
       <param-value>wxd667c09a8220e9eaparam-value>
    context-param>
  <context-param>
       <param-name>appSecretparam-name>
       <param-value>d3db5e22bfc9f761e4f70b3fe2bbd8b4param-value>
   context-param>
  
  <context-param>
       <param-name>demarcationparam-name>
       <param-value>100param-value>
   context-param>
  
  <error-page>
     <error-code>404error-code>
     <location>/404.htmllocation>
 error-page>

  
  
    <context-param>
       <param-name>driverparam-name>
       <param-value>com.mysql.jdbc.Driverparam-value>
    context-param>


    <context-param>
       <param-name>urlparam-name>
       <param-value>jdbc:mysql://localhost:3306/kaowuparam-value>
    context-param>

    <context-param>
       <param-name>usernameparam-name>
       <param-value>rootparam-value>
    context-param>

    <context-param>
       <param-name>passwordparam-name>
       <param-value>param-value>
    context-param>
web-app>

6.业务逻辑部分
1)审核
使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台_第4张图片
2.添加管理员
使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台_第5张图片
3.学院教务人员安排考试后台
使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台_第6张图片
4.新建考试完成后会向参加该门考试的教师托推送消息

package com.action.kaowu.sau.www;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.CoreServer.wechat.kaowu.sau.www.HttpRequest;
import com.bean.kaowu.sau.www.SpecificrecordBean;
import com.bean.kaowu.sau.www.TestBean;
import com.dao.kaowu.sau.www.OpenidDAO;
import com.dao.kaowu.sau.www.RegisterDAO;
import com.dao.kaowu.sau.www.SpecificrecordDAO;
import com.dao.kaowu.sau.www.TestDAO;
import com.opensymphony.xwork2.ActionSupport;
import com.units.wechat.kaowu.sau.edu.www.GetExistAccessToken;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class AffirmTest extends ActionSupport {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String testlist;
    private String testrecord;
    private String result;

    public String getTestlist() {
        return testlist;
    }

    public void setTestlist(String testlist) {
        this.testlist = testlist;
    }

    public String getTestrecord() {
        return testrecord;
    }

    public void setTestrecord(String testrecord) {
        this.testrecord = testrecord;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String execute() {

        synchronized (this) {

            // 获得到此次考试的时间+科目
            HttpSession session = ServletActionContext.getRequest().getSession();
            String Project = (String) session.getAttribute("Project");
            String Starttime = (String) session.getAttribute("Starttime");
            String Endtime = (String) session.getAttribute("Endtime");
            String College = (String) session.getAttribute("College_num");
            JSONObject jsonObject = JSONObject.fromObject(testlist);
            String testrecord = jsonObject.getString("testrecord");
            String arr_temp = jsonObject.getString("testlist");
            JSONArray array = JSONArray.fromObject(arr_temp);
            // 临时保存teacherid数据
            List ids = new ArrayList<>();
            List list = new ArrayList<>();
            for (int i = 0; i < array.size(); i++) {
                JSONObject o = array.getJSONObject(i);
                SpecificrecordBean js = new SpecificrecordBean();
                js.setClassid(o.getString("Classid"));
                js.setGradeid_1(o.getString("Gradeid_1"));
                js.setGradeid_2(o.getString("Gradeid_2"));
                js.setTeacherid_1(o.getString("Teacherid_1"));
                RegisterDAO.count(o.getString("Teacherid_1"));
                js.setTeacherid_2(o.getString("Teacherid_2"));
                RegisterDAO.count(o.getString("Teacherid_2"));
                js.setTestrecord(testrecord);
                list.add(js);
                // 向微信发送数据
                ids.add(o.getString("Teacherid_1"));
                ids.add(o.getString("Teacherid_2"));
            }
            SpecificrecordBean[] temp = new SpecificrecordBean[array.size()];
            for (int i = 0; i < temp.length; i++) {
                temp[i] = list.get(i);
            }
            TestBean testBean = new TestBean();
            testBean.setProject(Project);
            testBean.setStarttime(Starttime);
            testBean.setEndtime(Endtime);
            testBean.setTestid(testrecord);
            testBean.setCollege(Integer.parseInt(College));
            TestDAO.add(testBean);
            SpecificrecordDAO.add(temp);
            JSONObject jsonObject2 = new JSONObject();
            jsonObject2.put("list", temp);
            // 前端的数据
            result = jsonObject2.toString();

            // 调用微信的高级接口推送消息
            JSONArray Openid = new JSONArray();

            // 构建openid数据库查找sql
            StringBuilder builder = new StringBuilder();
            if (ids.size() > 0) {
                builder.append("where Therid in (");
                // 构造查询字符串
                int k = ids.size();
                for (int i = 0; i < k; i++) {
                    if (i == k - 1) {
                        builder.append(" '" + ids.get(i) + "')");
                    } else {
                        builder.append(" '" + ids.get(i) + "',");
                    }
                }
            }
            List openids = OpenidDAO.getOpenid(builder.toString());
            for (String s : openids) {
                Openid.add(s);
            }
            JSONObject ToAll = new JSONObject();
            JSONObject content = new JSONObject();
            content.put("content", "您近期有新的监考信息\n请点击考务助手\n我的监考查询");
            ToAll.put("touser", Openid);
            ToAll.put("msgtype", "text");
            ToAll.put("text", content);
            String url = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=ACCESS_TOKEN";
            String access_token = GetExistAccessToken.getToken().getToken();
            url = url.replace("ACCESS_TOKEN", access_token);
            HttpRequest.httpsRequest(url, "POST", ToAll.toString());
            return SUCCESS;
        }

    }

}

5.微信手机端预览
使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台_第7张图片

你可能感兴趣的:(JAVA)