首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

【OSS 排查方案-4】OSS + RTMP 推流的 JAVA 方法

背景:目前有很多直播爱好者使用的是 OSS + RTMP 做的推流直播,其中不乏一些企业级别应用,由于 OSS 作为推流的接收略微有一些复杂,故单独开篇讲一下。其实不建议使用 OSS+RTMP 做直播推流,因为功能性相比专业的阿里云直播几乎为 0 ,而且性能上并不好。建议大家使用单独的直播服务。 首先:看下官网对于 OSS 推流的过程定义 只能使用RTMP推流的方式,不支持拉流。 必须包含视频流,且视频流格式为H264。 音频流是可选的,并且只支持AAC格式,其他格式的音频流会被丢弃。 转储只支持HLS协议。 一个LiveChannel同时只能有一个客户端向其推流。 RTMP 的推流格式: rtmp://your-bucket.oss-cn-hangzhou.aliyuncs.com/live/test-channel live 等同于 RTMP

优秀的个人博客,低调大师

java程序员的10条建议,吐血推荐!

想清楚,再动手写代码 刚入行的新手,为了展示自己的能力,拿到需求迫不及待地就开始上手写代码,大忌! 不交流,就会头破血流 不爱说话和沟通,需求都理解错误了,最后做出来才发现,只能加班返工。 文档没人看,但还是要写 文档的作用大部分时候不是用来沟通的,是用来做记录的,大部分需求还是通过口头沟通,但是不写文档做记录,后续就容易扯皮。 一定要写注释 时间久了,你会连自己的代码都看不懂。 别指望需求会稳定 产品需求是根据商业需求不断调整的,改需求是再正常不过的事,别抱怨。 业务高于技术 如果技术不为公司商业做服务,那将毫无价值,公司赚钱才是硬道理。 不要心存侥幸 你隐约感觉会出bug的地方,就一定会出bug。 自己先测几遍 不要写完就扔给测试人员去测,经自己手的东西,要保证质量。 尽可能自己解决问题 遇到不懂的问题,要先尽力解决,别动不动就截个图扔在别人求帮忙,上司和同事不是来给你擦屁股的,但是真的搞砸了就要尽快求助。 慎用新技术 新技术是好东西,但没有百分百把握,自作主张用了,多半是作死。

优秀的个人博客,低调大师

关于微信支付和支付宝支付java实现

目前支付宝支付和微信支付是算是目前app的标配了 支付宝支付在更新过后有了官方专门的sdk和demo,所以相对而言比较简单,而微信支付稍微复杂一点,下面的文章会附实例代码,微信支付也是参考的github上的某位大神级人物的代码。 首先是微信支付 先准备各种数据,我一般都是放到配置类中,当然也可以放到数据库或者配置文件中 `public final class WxpayConfig { /** *商家可以考虑读取配置文件 */ //微信开发平台应用id public static final String APP_ID = "wx8888888888888888"; //财付通商户号 public static final String PARTNER = "1900000109";//app请求的商户号 public static final String MCHID = "1900000109";//预支付请求的商户号 //商户号对应的密钥 public static final String PARTNER_KEY = ""; //预支付接口 public static final String PREPAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //查询订单接口 public static final String QUERY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery"; //签名算法常量值 public static final String SIGN_METHOD = "sha1"; //异步通知地址 public static final String NOTIFY_URL = “”; //交易类型 public static final String TRADE_TYPE = "APP"; //暂定包值 public static final String PACKAGE = "Sign=WXPay"; //返回状态成功 public static final String SUCCESS = "SUCCESS"; //返回状态失败 public static final String FAIL = "FAIL"; }` 这是关于微信支付的封装的工具类,其中httpclient和md5加密的需要自己去封装工具类 `public class WxpayUtil { /** *随机串 * @return */ public static String getNonceStr() { Random random = new Random(); return MD5Util.getMD5String(String.valueOf(random.nextInt(10000))); } /** *时间戳 * @return */ public static String getTimeStamp() { return String.valueOf(System.currentTimeMillis() / 1000); } /** *解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。 * @param strxml * @return * @throws JDOMException * @throws IOException */ @SuppressWarnings("unchecked") public static Map parseToMap(String strXml) throws JDOMException, IOException { strXml = strXml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\""); if(null == strXml || "".equals(strXml)) { return null; } Map m = new HashMap<>(); InputStream in = new ByteArrayInputStream(strXml.getBytes("UTF-8")); SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(in); Element root = doc.getRootElement(); List list = root.getChildren(); Iterator it = list.iterator(); while(it.hasNext()) { Element e = it.next(); String k = e.getName(); String v = ""; List children = e.getChildren(); if(children.isEmpty()) { v = e.getTextNormalize(); } else { v = getChildrenText(children); } m.put(k, v); } //关闭流 in.close(); return m; } /** *获取子结点的xml * @param children * @return String */ @SuppressWarnings("unchecked") private static String getChildrenText(List children) { StringBuffer sb = new StringBuffer(); if(!children.isEmpty()) { Iterator it = children.iterator(); while(it.hasNext()) { Element e = it.next(); String name = e.getName(); String value = e.getTextNormalize(); List list = e.getChildren(); sb.append("<" + name + ">"); if(!list.isEmpty()) { sb.append(getChildrenText(list)); } sb.append(value); sb.append(""); } } return sb.toString(); } /** *只支持String,并且value非空 * @param map * @return */ public static String parseToXml(Map map){ StringBuffer sb = new StringBuffer(""); for(Map.Entry entry : map.entrySet()){ sb.append("<"+entry.getKey()+">"); sb.append(""); sb.append(""); } sb.append(""); return sb.toString(); } /** * POST提交XML对象 * @param document */ public static String postXmlClient(String url,String xmlParams) throws Exception { // return HttpUtils.postXmlEntity(url, xmlParams).getContent(); return HttpClient.postRequest(url, xmlParams); } } 这是关于微信支付一些参数处理的方法 public class WxpayHelper { /** *除去数组中的空值和签名参数 * @param sArray签名参数组 * @return去掉空值与签名参数后的新签名参数组 */ public static Map paraFilter(Map sArray) { Map result = new HashMap(); if (sArray == null || sArray.size() <= 0) { return result; } for (String key : sArray.keySet()) { String value = sArray.get(key); if (value == null || value.equals("") || key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("key")) { continue; } result.put(key, value); } return result; } /** *把数组所有元素,并按照“参数=参数值”的模式用“&”字符拼接成字符串 * @param params需要参与字符拼接的参数组 * @param sorts 是否需要排序 true 或者false * @return拼接后字符串 */ public static String createLinkString(Map params) { List keys = new ArrayList(params.keySet()); Collections.sort(keys); String prestr = ""; for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = params.get(key); if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符 prestr = prestr + key + "=" + value; } else { prestr = prestr + key + "=" + value + "&"; } } return prestr; } /** *验签响应签名 * @param paras * @return */ public static boolean verify(Map paras){ String sign = paras.get("sign"); if(StringUtils.isBlank(sign)) return false; return sign.equals(WxpayBuilder.buildRequestMysign(paraFilter(paras))); } /** *响应成功 * @param loggerAgent -日志代理 * @return String */ /*public static String yes(ILoggerAgent loggerAgent){ Map return_wx = new HashMap<>(); return_wx.put("return_code", WxpayConfig.SUCCESS); loggerAgent.payParamsLogger(null , "WX-NOTIFY", false, return_wx); return WxpayUtil.parseToXml(return_wx); }*/ } public class WxpayBuilder { /** *生成签名结果 * @param sPara要签名的数组 * @return签名结果字符串 */ public static String buildRequestMysign(Map sPara) { String prestr = WxpayHelper.createLinkString(sPara)+"&key="+WxpayConfig.PARTNER_KEY; LogFactory.getInstance().getLogger().debug("微信支付签名的字符串:"+prestr); return MD5Util.getMD5String(prestr).toUpperCase(); } public static Map buildRequestPara(Map sParaTemp) { //除去数组中的空值和签名参数 Map sPara = WxpayHelper.paraFilter(sParaTemp); //生成签名结果 String mysign = buildRequestMysign(sPara); LogFactory.getInstance().getLogger().debug("微信支付签名数据:"+mysign); //签名结果与签名方式加入请求提交参数组中 sPara.put("sign", mysign); return sPara; } }` 使用例程 其中业务接口信息,参考https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3 ` /** *微信订单逻辑 * * @throws Exception */ public Map wxPayLogic() throws Exception { //微信业务代码 Map xmlData = new HashMap(); xmlData.put("appid", WxpayConfig.APP_ID); xmlData.put("mch_id", WxpayConfig.MCHID); xmlData.put("nonce_str", WxpayUtil.getNonceStr()); xmlData.put("out_trade_no",); xmlData.put("total_fee",); xmlData.put("spbill_create_ip",“”); //从数据字典里面去主机地址 DataDictionary dataDictionary = dataDictionaryService.getDicByKey("PAY_CALLBACK"); xmlData.put("notify_url", dataDictionary.getValue() + WxpayConfig.NOTIFY_URL); xmlData.put("trade_type", WxpayConfig.TRADE_TYPE); xmlData.put("body", ""); //少写签名 Map result = WxpayBuilder.buildRequestPara(xmlData); // Map result = WxpayHelper.paraFilter(xmlData); String xmlParams = WxpayUtil.parseToXml(result); LogFactory.getInstance().getLogger().debug("微信支付请求报文:" + xmlParams); String xmlResult = WxpayUtil.postXmlClient(WxpayConfig.PREPAY_URL, xmlParams); Map map = WxpayUtil.parseToMap(xmlResult); LogFactory.getInstance().getLogger().debug("微信支付返回报文:" + JsonHelper.toJson(map)); //返回时SUCCESS if (WxpayConfig.SUCCESS.equals(map.get("return_code"))) { //验证返回是否成功 if (WxpayConfig.SUCCESS.equals(map.get("result_code"))) { //除去签名和空值 Map paraFilter = WxpayHelper.paraFilter(map); //获得签名 String mysign = WxpayBuilder.buildRequestMysign(paraFilter); //验证签名 if (mysign.equals(map.get("sign"))) { String prepay_id = map.get("prepay_id"); //验证签名成功 //进行操作 } else { //签名验证失败 LogFactory.getInstance().getLogger().debug("微信支付验证签名失败"); } } else { // result_code返回失败 String err_code = map.get("err_code"); String err_code_des = map.get("err_code_des"); chargeRecord.setCauses(err_code+err_code_des); LogFactory.getInstance().getLogger().debug("微信支付结果失败:失败码为"+err_code+",失败原因是"+err_code_des); chargeRecord.setState(2); } } else { // return_code返回失败 String return_msg = map.get("return_msg"); LogFactory.getInstance().getLogger().debug("微信支付返回失败:返回消息为:" + return_msg); return null; } //微信支付 Map mapBack = new HashMap<>(); mapBack.put("appid", WxpayConfig.APP_ID); mapBack.put("partnerid", WxpayConfig.PARTNER); mapBack.put("prepayid", chargeRecord.getOpenId()); mapBack.put("package", WxpayConfig.PACKAGE); mapBack.put("noncestr", WxpayUtil.getNonceStr()); mapBack.put("timestamp", WxpayUtil.getTimeStamp()); return WxpayBuilder.buildRequestPara(mapBack); }` 支付异步回传 接收到异步通知之后,才算是付款成功 `@Controller @RequestMapping(value = "/api") public class WxPayCallbackController extends BaseController { @Autowired OrderLogic orderLogic; @Autowired RedisFactory redisFactory; @Autowired ApplicationContext applicationContext; @RequestMapping(value = "/wxPayCallback", method = RequestMethod.POST) @ResponseBody public String wxPayCallback(@RequestBody String body) { MDC.put("seqID", SeqIdGenerator.generate());//日志序列 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付结果通知信息data=" + body); Map resultMap = new HashMap<>(); if (StringUtils.isNotBlank(body)) { try { Map map = WxpayUtil.parseToMap(body); //返回代码 if (WxpayConfig.SUCCESS.equals(map.get("return_code"))) { //验证签名 if (WxpayHelper.verify(map)) { //验证业务结果是否成功 String outTradeNo = map.get("out_trade_no"); if (WxpayConfig.SUCCESS.equals(map.get("result_code"))) { //设置支付类型,1为支付宝,2为微信 map.put("payType","2"); //通过所有验证,启动事件,通过spring的监听器进行监听,并执行付款成功后的业务 applicationContext.publishEvent(new OrderFinishEvent(map)); } else { //业务结果失败 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付业务结果失败"); orderLogic.updateState(outTradeNo,2); resultMap.put("return_code", WxpayConfig.SUCCESS); } } else { //签名失败 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付签名失败"); resultMap.put("return_code", WxpayConfig.FAIL); resultMap.put("return_msg", "签名失败"); } } else { //返回结果失败 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付返回结果失败"); resultMap.put("return_code", WxpayConfig.FAIL); resultMap.put("return_msg", "参数格式校验错误"); } } catch (Exception e) { e.printStackTrace(); } } else { //返回结果为空 LogFactory.getInstance().getPayCallbackLogger().info("参数格式校验错误"); resultMap.put("return_code", WxpayConfig.FAIL); resultMap.put("return_msg", "参数格式校验错误"); } return WxpayUtil.parseToXml(resultMap); } }` 付款成功统一处理事件监听 `@Component public class OrderFinishLister { @EventListener public void onApplicationEvent(OrderFinishEvent event){//这里不能抛出异常,外层无法处理,会造成中断 try { Map params = (HashMap) event.getSource(); String payType = params.get("payType"); String outTradeNo = params.get("out_trade_no"); String trade_no = null; String buyerLogonId = null; String buyerId = null; String transactionId = null; UserOrder order = null; if("1".equals(payType)){ //支付宝 trade_no = params.get("trade_no"); buyerLogonId = params.get("buyer_logon_id"); buyerId = params.get("buyer_id"); //执行付款成功后的业务逻辑 LogFactory.getInstance().getLogger().debug("支付宝获取支付更新状态:" + outTradeNo); }else if("2".equals(payType)){ //微信 transactionId = params.get("transaction_id"); //执行微信付款成功后的业务逻辑 LogFactory.getInstance().getLogger().debug("微信获取支付更新状态:" + outTradeNo); } }catch (Exception e){ e.printStackTrace(); } } }` 这就是单独的微信支付业务流程

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册