`
空指针异常
  • 浏览: 22745 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

微信开发

wx 
阅读更多
参考文章
http://www.cnblogs.com/txw1958/p/weixin-qrcode-with-parameters.html
http://tuposky.iteye.com/blog/2082230
https://github.com/caspar-chen/WechatSDK

@Action("wxAction")
public class WeixinAction extends ActionSupport {
	public static final Logger logger = Logger.getLogger(WeixinAction.class);
	
	@Autowired
	private WXUserService wxUserService;

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public String execute() throws Exception {
		HttpServletRequest req = ServletActionContext.getRequest();
		PrintWriter out = ServletActionContext.getResponse().getWriter();
		String method = req.getMethod();
		if (WXConstants.METHOD_GET.equals(method)) {
			// 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数
			String signature = req.getParameter("signature");
			// 时间戳
			String timestamp = req.getParameter("timestamp");
			// 随机数
			String nonce = req.getParameter("nonce");
			// 随机字符串
			String echostr = req.getParameter("echostr");

			// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
			if (SignUtil.checkSignature(signature, timestamp, nonce)) {
				out.print(echostr);
			}
		} else if (WXConstants.METHOD_POST.equals(method)) {
			// xml请求解析
			Map<String, String> reqMap = MessageUtil.parseXml(req);

			// 消息类型
			String msgType = reqMap.get("MsgType");
			if (msgType.equals(WXConstants.REQ_MESSAGE_TYPE_EVENT)) {
				String eventType = reqMap.get("Event");
				String openID = reqMap.get("FromUserName");
				String ticket = reqMap.get("Ticket");
				// 获取用户基本信息
				String nickname = WXInterfaceUtil.getNickname(openID);
				// 用户未关注时
				if (eventType.equals(WXConstants.EVENT_TYPE_SUBSCRIBE)) {
					logger.info("新关注用户openID:" + openID);
				}
				// 用户已关注
				else if (eventType.equals(WXConstants.EVENT_TYPE_SCAN)) {
					logger.info("已关注用户openID:" + openID);
				}
				// 更新数据库
				wxUserService.updateUserInfoByTicket(ticket, nickname, openID);
			}
		}

		out.close();
		out = null;
		return null;
	}
}


@Action("qrcodeCreateAction")
public class QrcodeCreateAction extends ActionSupport {
	@Autowired
	private WXUserService wxUserService;
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -7930634700220791363L;
	
	@Override
	public String execute() throws Exception {
		PrintWriter out = ServletActionContext.getResponse().getWriter();
		// 获取传输的参数SN
		String sn = ServletActionContext.getRequest().getParameter("sn");
		
		// 生成临时二维码,每次生成二维码时ticket不一样,当用户扫描二维码时,可根据ticket更新关联的记录
		// 不能用永久二维码,因为永久二维码每次产生的ticket每次都一样
		String accessToken = WXInterfaceUtil.getAccessToken();
		String ticket = WXInterfaceUtil.createTempQrcode(accessToken);
		if(null == ticket){
			WXInterfaceUtil.access_token = null;
			accessToken = WXInterfaceUtil.getAccessToken();
			ticket = WXInterfaceUtil.createTempQrcode(accessToken);
		}
		
		//将当前请求的数据存入数据库,如果当前sn在数据库中已有记录,更新ticket,如果没有,新增一条记录
		wxUserService.saveOrUpdateUserInfo(sn, ticket);
		
		JSONObject obj = new JSONObject();
		//如果取ticket失败
		if(null == ticket){
			obj.put("errcode", "99");
			obj.put("errmsg", "failure");
		}else{
			//组装生成二维码URL,get请求
			String qrCodeUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket;
			obj.put("qrCodeUrl", qrCodeUrl);
			obj.put("errcode", "0");
			obj.put("errmsg", "success");
		}
		out.print(obj.toString());
		return null;
	}
}


@Service
public class WXUserServiceImpl implements WXUserService {
	
	@Autowired
	private WXUserDao wxUserDao;
	/**
	 * 当安卓客户端请求二维码时,如果当前请求的盒子信息没有保存在数据库中,则新增数据至数据库。
	 * 如果当前盒子已经请求过二维码,将ticket更新,并且清空用户信息
	 * 
	 * @param sn
	 * @param ticket
	 */
	public void saveOrUpdateUserInfo(String sn,String ticket){
		WXUser user = wxUserDao.getBySN(sn);
		//如果用户不存在
		if(null == user){
			WXUser u = new WXUser();
			u.setSn(sn);
			u.setTicket(ticket);
			u.setCreateTime(new Date());
			wxUserDao.save(u);
		}
		//用户已存在,更新ticket,清空用户信息
		else{
			user.setTicket(ticket);
			user.setCreateTime(new Date());
			user.setNickname("");
			user.setOpenId("");
			user.setLastLoginTime(null);
			user.setFlag(0);
			wxUserDao.update(user);
		}
	}
	
	/**
	 * 用户扫描二维码,用户根据ticket更新用户信息
	 * 
	 * @param ticket
	 * @param nickname
	 * @param openId
	 */
	public void updateUserInfoByTicket(String ticket,String nickname,String openId){
		WXUser user = wxUserDao.getByTicket(ticket);
		user.setNickname(nickname);
		user.setOpenId(openId);
		user.setLastLoginTime(new Date());
		wxUserDao.update(user);
	}
}


public class MessageUtil {
    /**
     * 解析微信发来的请求(XML)
     * 
     * @param request
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<String, String>();

        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();

        // 遍历所有子节点
        for (Element e : elementList)
                map.put(e.getName(), e.getText());

        // 释放资源
        inputStream.close();
        inputStream = null;

        return map;
    }
}

public class ReqUtil {
	private static final Logger logger = Logger.getLogger(ReqUtil.class);
	
	/**
	 * POST 请求
	 * 
	 * @param reqUrl
	 * @param reqParams
	 * @return String
	 */
	public static String post(String reqUrl, String params) {
		logger.info("POST Request,Url:" + reqUrl);
		DataOutputStream outStream = null;
		HttpURLConnection conn = null;
		String result = "";
		try {
			byte[] data = params.toString().getBytes();
			URL realUrl = new URL(reqUrl);
			conn = (HttpURLConnection) realUrl
					.openConnection();
			conn.setDoOutput(true);// 发送POST请求必须设置允许输出
			conn.setUseCaches(false);// 不使用Cache
			conn.setRequestMethod(WXConstants.METHOD_POST);
			conn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
			conn.setRequestProperty("Charset", "UTF-8");
			conn.setRequestProperty("Content-Length",
					String.valueOf(data.length));
			conn.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			outStream = new DataOutputStream(
					conn.getOutputStream());
			outStream.write(data);
			outStream.flush();
			if (conn.getResponseCode() == 200) {
				result = readData(conn.getInputStream(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			if(null != outStream){
				try {
					outStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(null != conn){
				conn.disconnect();
			}
		}
		return result;
	}

	/**
	 * Get 请求
	 * 
	 * @param reqUrl
	 * @return String
	 */
	public static String get(String reqUrl) {
		logger.info("GET Request,Url:" + reqUrl);
		InputStream is = null;
		HttpURLConnection conn = null;
		String result = "";
		try {
			URL url = new URL(reqUrl);
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5 * 1000);// 设置连接超时
			conn.setRequestMethod(WXConstants.METHOD_GET);// 以get方式发起请求
			if (conn.getResponseCode() != 200)
				throw new RuntimeException("请求url失败");
			is = conn.getInputStream();// 得到网络返回的输入流
			result = readData(is, "UTF-8");
			conn.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			if(null != is){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(null != conn){
				conn.disconnect();
			}
		}
		return result;
	}

	/**
	 * 第一个参数为输入流,第二个参数为字符集编码
	 * 
	 * @param inSream
	 * @param charsetName
	 * @return String
	 * @throws Exception
	 */
	private static String readData(InputStream inSream, String charsetName)
			throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = inSream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		byte[] data = outStream.toByteArray();
		outStream.close();
		inSream.close();
		return new String(data, charsetName);
	}
}


public class SignUtil {
	// Token可由开发者任意填写,用作生成签名
	private static final String token = "test";
	
	/**
	 * 检验signature对请求进行校验,确认此次GET请求来自微信服务器
	 * 
	 * @param signature
	 * @param token
	 * @param timestamp
	 * @param nonce
	 * @return boolean
	 */
	public static boolean checkSignature(String signature,String timestamp,String nonce){
		String[] arr = new String[]{token, timestamp, nonce};
		// 将token、timestamp、nonce三个参数进行字典序排序
		Arrays.sort(arr);
		// 拼装成字符串
		StringBuilder content = new StringBuilder();
		for(String str : arr){
			content.append(str);
		}
		
		// sha1加密
		MessageDigest md = null;
		String tmpStr = null;
		try {
			md = MessageDigest.getInstance("SHA-1");
			// 将三个参数字符串拼接成一个字符串进行sha1加密
			byte[] digest = md.digest(content.toString().getBytes());
			tmpStr = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		
		content = null;
		// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
		return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
	}
	
	/**
	 * 将字节数组转换为十六进制字符串
	 * 
	 * @param byteArray
	 * @return String
	 */
	private static String byteToStr(byte[] byteArray) {
		StringBuilder strDigest = new StringBuilder();
		for (int i = 0; i < byteArray.length; i++) {
			strDigest.append(byteToHexStr(byteArray[i]));
		}
		return strDigest.toString();
	}
	
	/**
	 * 将字节转换为十六进制字符串
	 * 
	 * @param mByte
	 * @return String
	 */
	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];

		String s = new String(tempArr);
		return s;
	}
}

public class WXInterfaceUtil {
	private static final Logger logger = Logger
			.getLogger(WXInterfaceUtil.class);

	/**
	 * access_token有效期为7200秒,不需要每次都去调用
	 */
	public static String access_token = null;

	/**
	 * 获取access_token
	 * 
	 * @return String
	 */
	public static String getAccessToken() {
		if (null == access_token) {
			// 获取ACCESS_TOKEN
			String reqUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
					+ WXConstants.APPID + "&secret=" + WXConstants.APPSECRET;
			String result = ReqUtil.get(reqUrl);
			logger.info("get access token,result:" + result);
			JSONObject obj = JSONObject.fromObject(result);
			access_token = (String) obj.get("access_token");
			logger.info("access_token: " + access_token);
		}
		return access_token;
	}

	/**
	 * 获取用户呢称
	 * 
	 * @param openID
	 * @return String
	 */
	public static String getNickname(String openID) {
		String reqUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="
				+ getAccessToken() + "&openid=" + openID + "&lang=zh_CN";
		String result = ReqUtil.get(reqUrl);
		logger.info("get nickname,result:" + result);
		JSONObject obj = JSONObject.fromObject(result);
		String nickname = (String) obj.get("nickname");
		
		logger.info("nickname: " + nickname);
		return nickname;
	}

	/**
	 * 创建临时二维码
	 * 
	 * @return String
	 */
	public static String createTempQrcode(String accessToken) {
		String reqUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="
				+ accessToken;
		String params = "{\"expire_seconds\": " + WXConstants.EXPIRE_SECONDS
				+ ", \"action_name\": \"" + WXConstants.ACTION_NAME
				+ "\", \"action_info\": {\"scene\": {\"scene_id\": "
				+ WXConstants.SCENE_ID + "}}}";
		String result = ReqUtil.post(reqUrl, params);
		logger.info("create temp qrcode,result:" + result);
		JSONObject obj = JSONObject.fromObject(result);
		String ticket = (String)obj.get("ticket");
		logger.info("ticket: " + ticket);
		return ticket;
	}
}
分享到:
评论

相关推荐

    风力发电机控制系统仿真设计 风力发电系统动态模拟仿真 光伏发电系统 本设计主要依据风力发电机组的控制目标和控制策略,通过使用电力系统动态模拟仿真软件PSCAD EMTDC,建立变桨距风力发电机组控制系

    风力发电机控制系统仿真设计 风力发电系统动态模拟仿真 光伏发电系统 本设计主要依据风力发电机组的控制目标和控制策略,通过使用电力系统动态模拟仿真软件PSCAD EMTDC,建立变桨距风力发电机组控制系统的模型。 为了验证控制系统模型的可用性,建立风力发电样例系统模型,对样例系统进行模拟仿真,并对所得的仿真结果进行了分析,从而证实了风力发电机组控制系统模型的可用性,然后得出了它的控制方法。

    安卓项目源码Androidafinal开源框架实例源码

    安卓项目源码Android afinal开源框架实例源码提取方式是百度网盘分享地址

    C4网络技术挑战赛B-EP1赛道解决方案与实践.zip

    C4网络技术挑战赛B-EP1赛道解决方案与实践.zip [资源说明] 1、该项目是团队成员近期最新开发,代码完整,资料齐全,含设计文档等 2、上传的项目源码经过严格测试,功能完善且能正常运行,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的高校学生、教师、科研工作者、行业从业者下载使用,可借鉴学习,也可直接作为毕业设计、课程设计、作业、项目初期立项演示等,也适合小白学习进阶,遇到问题不懂就问,欢迎交流。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 5、不懂配置和运行,可远程教学 6、欢迎下载,沟通交流,互相学习,共同进步!

    Bandgap 带隙基准,带启动电路,带版图 适合新手练习 主要包含以下仿真内容: 温度特性曲线 电源抑制比psrr仿真 稳定性仿真,整个环路的稳定性 噪声仿真,可以知道噪声的主要贡献来源 输出电压精

    Bandgap 带隙基准,带启动电路,带版图 适合新手练习 主要包含以下仿真内容: 温度特性曲线 电源抑制比psrr仿真 稳定性仿真,整个环路的稳定性 噪声仿真,可以知道噪声的主要贡献来源 输出电压精度仿真 [cool][cool]testbench有单独的仿真状态,直接安装可以运行 性价比高,可以买回去练一练

    工程机器人大赛(含全部参赛源码及资料).zip

    工程机器人大赛(含全部参赛源码及资料).zip [资源说明] 1、该项目是团队成员近期最新开发,代码完整,资料齐全,含设计文档等 2、上传的项目源码经过严格测试,功能完善且能正常运行,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的高校学生、教师、科研工作者、行业从业者下载使用,可借鉴学习,也可直接作为毕业设计、课程设计、作业、项目初期立项演示等,也适合小白学习进阶,遇到问题不懂就问,欢迎交流。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 5、不懂配置和运行,可远程教学 6、欢迎下载,沟通交流,互相学习,共同进步!

    汽车中间件市场调研报告:2023年全球汽车中间件市场销售额达到了78亿美元

    汽车中间件市场调研报告:2023年全球汽车中间件市场销售额达到了78亿美元 在数字化转型的浪潮中,汽车中间件作为连接硬件与软件的关键桥梁,正引领着汽车行业的新一轮变革。随着全球汽车产业的快速发展,中间件市场规模持续扩大,展现出前所未有的增长潜力。然而,面对复杂多变的市场环境和不断涌现的新技术,企业如何精准把握市场脉搏,实现可持续发展?本文将深入探讨全球及中国汽车中间件市场的现状、趋势及竞争格局,为您揭示咨询的重要性。 市场概况: 根据QYResearch(恒州博智)的统计及预测,2023年全球汽车中间件市场销售额达到了78亿美元(约7803百万美元),预计2030年将达到156亿美元(约15630百万美元),年复合增长率(CAGR)为10.3%(2024-2030)。这一数据不仅彰显了中间件市场的强劲增长动力,也预示着未来巨大的市场空间。 技术创新与趋势: 随着自动驾驶、车联网等技术的不断发展,汽车中间件正面临着前所未有的技术挑战与机遇。新一代中间件需要具备更高的实时性、更低的延迟以及更强的数据处理能力,以满足复杂多变的汽车应用场景。同时,云计算、大数据、人工智能等技术的融合应用,将进

    基于梯度方向的VVC帧内编码中CU划分早终止算法研究与实现

    内容概要:本文探讨了一种在VVC(Versatile Video Coding)帧内编码中基于梯度方向特性的早期终止算法,旨在减少不必要的搜索从而优化计算复杂度。文中分析了视频编码的统计特征以及不同方向梯度的影响来指导CU(Coding Unit)分割决策流程。此外还介绍了算法的具体操作步骤和逻辑分支条件。实验结果显示该方法能够显著节省编码时间,平均达到约38%-51%,尽管BD-rate有所牺牲但总体上提升了效率并保持了较好的编码性能。 适合人群:从事多媒体通信系统开发或者图像视频压缩技术领域的研究人员和工程师,特别是那些对高分辨率影像处理感兴趣的专业人士。 使用场景及目标:本研究适用于寻求提高VVC标准下编码速度而不大幅度降低质量的应用环境中,如高清或超高清实时流媒体传输和服务提供者希望加快转码过程的情况。 其他说明:作者感谢中国国家重点研发计划和其他项目对于此项工作的支持,并提供了丰富的参考文献列表用于进一步的研究。

    占空比可调方波.ms14

    占空比可调方波.ms14

    基于matlab的单指针百分数表盘识别系统 表盘识别基于计算机视觉设计,基于霍夫变算法,含GUI界面 步骤:灰度化,二值化,反色,细化,霍夫变,提取峰值,检测识别 功能:识别单指针仪表盘,显示仪表

    基于matlab的单指针百分数表盘识别系统 【表盘识别】基于计算机视觉设计,基于霍夫变算法,含GUI界面 步骤:灰度化,二值化,反色,细化,霍夫变,提取峰值,检测识别 功能:识别单指针仪表盘,显示仪表指针角度以及仪表示数,显示二值化图像,灰度化图像,变域图像。 代码结构清晰,含有注释,运算速度快,可扩展。

    简单的HTML和JavaScript代码,跨年倒计时html代码

    跨年倒计时html代码

    级联H桥储能变器,级联H桥整流器 采用栽波移相调制,功率外环电流内环控制; 相内SOC为基波均衡分量注入,相间SOC为零序电压注入法,可在短时间内使得SOC达到平衡, 下图为2单元五电平,可做多模块级

    级联H桥储能变器,级联H桥整流器 采用栽波移相调制,功率外环电流内环控制; 相内SOC为基波均衡分量注入,相间SOC为零序电压注入法,可在短时间内使得SOC达到平衡, 下图为2单元五电平,可做多模块级联,H桥整流等 提供参考文献,,Matlab为2018b

    adaceshiwaifa,adaceshiwaifa,adaceshiwaifa,adaceshiwaifa

    adaceshiwaifa,adaceshiwaifa,adaceshiwaifa,adaceshiwaifa

    光伏交直流混合微电网双下垂控制离网(孤岛)模式Matlab仿真模型 ①交直流混合微电网结构: 1.直流微电网,由光伏板+Boost变器组成,最大输出功率10 kW 2.交流微电网,由光伏板+Boos

    光伏交直流混合微电网双下垂控制离网(孤岛)模式Matlab仿真模型 ①交直流混合微电网结构: 1.直流微电网,由光伏板+Boost变器组成,最大输出功率10 kW。 2.交流微电网,由光伏板+Boost变器+LCL逆变器组成,最大输出功率15 kW。 3.互联变器(ILC),由LCL逆变器组成,用于连接交直流微电网。 ②模型内容: 1.直流微电网:采用下垂控制,控制方式为电压电流双闭环,直流母线额定电压700 V。 2.交流微电网中,Boost变器采用恒压控制,直流电容电压为700 V,LCL逆变器采用下垂控制,额定频率50 Hz,额定相电压有效值220 V。 3.ILC采用双下垂控制策略,首先将交流母线频率和直流母线电压进行归一化,使其范围控制在[-1,1],之后通过ILC的归一化下垂控制调节交流母线频率和直流母线电压的偏差,最终使二者数值相同。 4.其余部分包括采样保持、坐标变、功率滤波、SVPWM等环节。 ③仿真工况:0.75 s时刻负载由12 kW增至16 kW,可以看出系统仍能稳定运行,波形质量良好,且交流母线频率和直流母线电压归一化的参数在ILC控制下趋于一致。

    基于SpringBoot+Vue.JS开发的校园闲置物品交易系统 JAVA毕业设计 源码+数据库+论文(有项目截图)+启动教程

    基于SpringBoot+Vue.JS开发的校园闲置物品交易系统 JAVA毕业设计 源码+数据库+论文(有项目截图)+启动教程

    Android Studio实现学生信息管理系统源码(高分项目).zip

    Android Studio实现学生信息管理系统源码(高分项目).zip个人经导师指导并认可通过的高分大作业项目,评审分98分,项目中的源码都是经过本地编译过可运行的,都经过严格调试,确保可以运行!主要针对计算机相关专业的正在做大作业的学生和需要项目实战练习的学习者,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 Android Studio实现学生信息管理系统源码(高分项目).zipAndroid Studio实现学生信息管理系统源码(高分项目).zipAndroid Studio实现学生信息管理系统源码(高分项目).zipAndroid Studio实现学生信息管理系统源码(高分项目).zipAndroid Studio实现学生信息管理系统源码(高分项目).zipAndroid Studio实现学生信息管理系统源码(高分项目).zipAndroid Studio实现学生信息管理系统源码(高分项目).zipAndroid Studio实现学生信息管理系统源码(高分项目).zipAndroid Studio实现学生信息管理

    VTK User's Guide第四版(最新的)-中文翻译版PDF

    VTK User's Guide双语版PDF

    国科大 并发数据结构与多核编程.zip

    国科大 并发数据结构与多核编程国科大并发数据结构与多核编程 -- 列车售票系统目录1. 基本结构的实现2. 使用位图加速余票查询3. 使用位图加速购票4. 懒惰计算5. 简单测试1. 基本结构的实现接下来叙述的实现均以下面的场景为例一共有三个站台一共有两趟车每趟车两节车厢,每节车厢两个座位 在本系统的时间中,将上述的应用场景表示为下图中的形式 如上图中所示,系统中会将三个站台之间的所有座位都表示出来,每一个车次使用一个单独的表示座位的数组表示,一共(2*2*2*2)16个座位,由于购票时用户只需要指定出发站、终点站以及车次号,因此系统仅需区分不同车次的座位,而对同一车次中的不同车厢的座位同等对待,车次中的每一个座位可以表示为一个类,如下面的形式class Seat { private Lock lock; private boolean available; public Seat() { } public void lock() { } public void unlock() {

    毕设&课程作业_基于C#的Winform公司管理系统.zip

    计算机系毕业设计

    过年倒计时动画html过年倒计时代码/春节倒计时网页版【春节倒计时html】

    过年倒计时动画html过年倒计时代码/春节倒计时网页版【春节倒计时html】 效果演示:https://www.ygwzjs.cn/cjdjs/ 备用一:cjdjswww.vbjcw.cn 备用二:cjdjswww.lxsjfx.cn 备用三:cjdjswww.seoheimao.cn 如果第一个看不了,就看其它备用的哦 过年倒计时动画html过年倒计时代码/春节倒计时网页版【春节倒计时html】

Global site tag (gtag.js) - Google Analytics