SpringBootServletInitializer 的作用
Posted 89564f
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBootServletInitializer 的作用相关的知识,希望对你有一定的参考价值。
SpringBootServletInitializer
是一个 Spring Boot 提供的用于配置 Servlet 初始化器的类。它继承自 Spring 的 SpringServletContainerInitializer
类,实现了 WebApplicationInitializer
接口,因此可以在 Servlet 容器启动时自动被加载,并生成一个 servlet 容器的配置类,用于初始化 Servlet 容器。
在 Spring Boot 应用中,如果需要将应用打包成 WAR 包并部署到外部的 Servlet 容器中,就需要使用 SpringBootServletInitializer
。通过创建一个继承自 SpringBootServletInitializer
的类,并在该类中重写 configure()
方法,可以创建一个 Servlet 容器初始化器,用于配置外部的 Servlet 容器。例如:
public class MyWebApplicationInitializer extends SpringBootServletInitializer
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
return application.sources(MySpringBootApplication.class);
上述代码创建了一个 MyWebApplicationInitializer
类,继承自 SpringBootServletInitializer
。它重写了 configure()
方法,该方法返回一个 SpringApplicationBuilder
对象,用于配置 Spring Boot 应用程序的其他设置。在本例中,configure()
方法指定了 Spring Boot 应用程序的启动类为 MySpringBootApplication.class
,这样在部署 WAR 包时,Servlet 容器会自动加载这个类,并启动 Spring Boot 应用程序。
总的来说,SpringBootServletInitializer
的作用是让 Spring Boot 应用程序可以以 WAR 包的形式部署到外部的 Servlet 容器(如 Tomcat、Jetty 等),并提供一种简单的方式来配置外部 Servlet 容器。
c#版在pc端发起微信扫码支付
等了好久,微信官方终于发布了.net的demo。
主要代码:
/** * 生成直接支付url,支付url有效期为2小时,模式二 * @param productId 商品ID * @return 模式二URL */ public string GetPayUrl(string productId, string body, string attach, int total_fee, string goods_tag) { Log.Info(this.GetType().ToString(), "Native pay mode 2 url is producing..."); WxPayData data = new WxPayData(); data.SetValue("body", body);//商品描述 data.SetValue("attach", attach);//附加数据 data.SetValue("out_trade_no", productId);//随机字符串 data.SetValue("total_fee", total_fee);//总金额 data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始时间 data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易结束时间 data.SetValue("goods_tag", goods_tag);//商品标记 data.SetValue("trade_type", "NATIVE");//交易类型 data.SetValue("product_id", productId);//商品ID WxPayData result = WxPayApi.UnifiedOrder(data);//调用统一下单接口 string url = result.GetValue("code_url").ToString();//获得统一下单接口返回的二维码链接 Log.Info(this.GetType().ToString(), "Get native pay mode 2 url : " + url); return url; }
配置信息:
public class Config { //=======【基本信息设置】===================================== /* 微信公众号信息配置 * APPID:绑定支付的APPID(必须配置) * MCHID:商户号(必须配置) * KEY:商户支付密钥,参考开户邮件设置(必须配置) * APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置) */ public const string APPID = "你的微信公众号APPID"; public const string MCHID = "你的微信公众号的商户号"; public const string KEY = "你的微信公众号的商户支付密钥"; public const string APPSECRET = "你的微信公众号的APPSECRET"; //=======【证书路径设置】===================================== /* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要) */ public const string SSLCERT_PATH = "cert/apiclient_cert.p12"; public const string SSLCERT_PASSWORD = "1233410002"; //=======【支付结果通知url】===================================== /* 支付结果通知回调url,用于商户接收支付结果 */ public const string NOTIFY_URL = "http://你的网站/Pay/ResultNotifyPage.aspx"; //=======【商户系统后台机器IP】===================================== /* 此参数可手动配置也可在程序中自动获取 */ public const string IP = "你的服务器IP"; //=======【代理服务器设置】=================================== /* 默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置) */ public const string PROXY_URL = ""; //=======【上报信息配置】=================================== /* 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报 */ public const int REPORT_LEVENL = 1; //=======【日志级别】=================================== /* 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息 */ public const int LOG_LEVENL = 0; }
不使用代理要注释HttpService.cs里面post和get方法的下面代码:
//设置代理服务器 //WebProxy proxy = new WebProxy(); //定义一个网关对象 //proxy.Address = new Uri(Config.PROXY_URL); //网关服务器端口:端口 //request.Proxy = proxy;
统一下单:
/** * * 统一下单 * @param WxPaydata inputObj 提交给统一下单API的参数 * @param int timeOut 超时时间 * @throws WxPayException * @return 成功时返回,其他抛异常 */ public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //检测必填参数 if (!inputObj.IsSet("out_trade_no")) { throw new WxPayException("缺少统一支付接口必填参数out_trade_no!"); } else if (!inputObj.IsSet("body")) { throw new WxPayException("缺少统一支付接口必填参数body!"); } else if (!inputObj.IsSet("total_fee")) { throw new WxPayException("缺少统一支付接口必填参数total_fee!"); } else if (!inputObj.IsSet("trade_type")) { throw new WxPayException("缺少统一支付接口必填参数trade_type!"); } //关联参数 if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid")) { throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!"); } if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id")) { throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!"); } //异步通知url未设置,则使用配置文件中的url if (!inputObj.IsSet("notify_url")) { inputObj.SetValue("notify_url", Config.NOTIFY_URL);//异步通知url } inputObj.SetValue("appid", Config.APPID);//公众账号ID inputObj.SetValue("mch_id", Config.MCHID);//商户号 inputObj.SetValue("spbill_create_ip", Config.IP);//终端ip inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串 //签名 inputObj.SetValue("sign", inputObj.MakeSign()); string xml = inputObj.ToXml(); var start = DateTime.Now; Log.Debug("WxPayApi", "UnfiedOrder request : " + xml); string response = HttpService.Post(xml, url, false, timeOut); Log.Debug("WxPayApi", "UnfiedOrder response : " + response); var end = DateTime.Now; int timeCost = (int)((end - start).TotalMilliseconds); WxPayData result = new WxPayData(); result.FromXml(response); ReportCostTime(url, timeCost, result);//测速上报 return result; }
看我的调用例子:
MakeQRCode.aspx页面照抄:
public partial class Pay_MakeQRCode : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!string.IsNullOrEmpty(base.Request.QueryString["data"])) { string str = base.Request.QueryString["data"]; Bitmap image = new QRCodeEncoder { QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE, QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M, QRCodeVersion = 0, QRCodeScale = 4 }.Encode(str, Encoding.Default); MemoryStream ms = new MemoryStream(); image.Save(ms, ImageFormat.Png); base.Response.BinaryWrite(ms.GetBuffer()); base.Response.End(); } } }
这个页面是用来生成二维码的,需要引入ThoughtWorks.QRCode.dll组件。
我使用模式二,回调页面是ResultNotifyPage.aspx,就是在配置信息那里填写的那个回调页面。
protected void Page_Load(object sender, EventArgs e) { ResultNotify resultNotify = new ResultNotify(this); WxPayData res = resultNotify.ProcessNotify2(); if (res.GetValue("return_code") == "SUCCESS") { //查询微信订单信息 string paySignKey = ConfigurationManager.AppSettings["paySignKey"].ToString(); string mch_id = ConfigurationManager.AppSettings["mch_id"].ToString(); string appId = ConfigurationManager.AppSettings["AppId"].ToString(); QueryOrder queryorder = new QueryOrder(); queryorder.appid = appId; queryorder.mch_id = mch_id; queryorder.transaction_id = res.GetValue("transaction_id").ToString(); queryorder.out_trade_no = ""; queryorder.nonce_str = TenpayUtil.getNoncestr(); TenpayUtil tenpay = new TenpayUtil(); OrderDetail orderdeatil = tenpay.getOrderDetail(queryorder, paySignKey); //写微信记录 (new vinson()).WriteReturnWXDetail(orderdeatil); //写充值记录 FilliedOnline(orderdeatil.out_trade_no); } Response.Write(res.ToXml()); Response.End(); }
扫码支付成功后会异步到这个页面执行代码,我们自己的业务逻辑就要写在这里。使用微信官方的ProcessNotify()函数可不行,我们稍微修改下就好了。增加ProcessNotify2函数:
public WxPayData ProcessNotify2() { WxPayData notifyData = GetNotifyData(); //检查支付结果中transaction_id是否存在 if (!notifyData.IsSet("transaction_id")) { //若transaction_id不存在,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("transaction_id", ""); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "支付结果中微信订单号不存在"); return res; } string transaction_id = notifyData.GetValue("transaction_id").ToString(); //查询订单,判断订单真实性 if (!QueryOrder(transaction_id)) { //若订单查询失败,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("transaction_id", transaction_id); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "订单查询失败"); return res; } //查询订单成功 else { WxPayData res = new WxPayData(); res.SetValue("transaction_id", transaction_id); res.SetValue("return_code", "SUCCESS"); res.SetValue("return_msg", "OK"); return res; } }
返回WxPayData对象,这样一判断
if (res.GetValue("return_code") == "SUCCESS")
表示支付成功,就可以进入我们的业务逻辑。
然后我们还要对当前订单查单,获取订单的相关信息,之前微信未出demo的时候我自己写了个查单的,就直接用了,关键WxPayData对象会返回微信的订单号:res.GetValue("transaction_id").ToString()。
完事后还要发送信息回给微信,通知微信后台不要继续发送异步请求了:
Response.Write(res.ToXml());
Response.End();
这个代码比较重要了。
再说说放置二维码的页面:
<div class="g-body"> <div class="g-wrap"> <div class="m-weixin"> <div class="m-weixin-header"> <p><strong>请您及时付款,以便订单尽快处理!订单号:<asp:Label ID="trade_no" runat="server" Text="Label"></asp:Label></strong></p> <p>请您在提交订单后1小时内支付,否则订单会自动取消。</p> </div> <div class="m-weixin-main"> <h1 class="m-weixin-title"> <img alt="微信支付" src="../images/wxlogo_pay.png"/> </h1> <p class="m-weixin-money"><font>扫一扫付款</font><br/><strong>¥<asp:Label ID="money" runat="server" Text="Label"></asp:Label></strong></p> <p> <img id="payQRImg" width="260" height="260" class="m-weixin-code" style="position: absolute;" src="<%=ImageUrl %>" alt="二维码" style="border-width:0px;" /> <img class="m-weixin-demo" src="../images/wxwebpay_guide.png" alt="扫一扫" /> <img style="margin-top:300px;" src="../images/weixin_1.png" alt="请使用微信扫描二维码以完成支付" /> </p> <p id="we_ok" style="display:none;"> <input value="完成" style="width: 300px; height: 50px; background: rgb(21, 164, 21) none repeat scroll 0% 0%; color: white; font-size: 30px; border: medium none; cursor: pointer;" type="button" /> </p> </div> </div> </div> </div>
写个js查单支付情况进行显示:
$(function () { var success = "<%=success %>"; if (success == "error") { $(".g-body").hide(); } }) var iCount = setInterval(check, 2000); //每隔2秒执行一次check函数。 function check() { $.ajax({ contentType: "application/json", url: "/WebService/vinson.asmx/queryWeiXin", data: "{OrderID:‘" + $("#trade_no").text() + "‘}", type: "POST", dataType: "json", success: function (json) { json = eval("(" + json.d + ")"); if (json.success == "success") { clearInterval(iCount); $(".m-weixin-money font").html("已成功付款"); $("#payQRImg").remove(); $(".m-weixin-demo").before(‘<img src="../images/wx_ok.jpg" width="200">‘); $(".m-weixin-demo").next().remove(); $("#we_ok").show(); } }, error: function (err, ex) { } }); }
是的,我又写了个给ajax使用的查单函数queryWeiXin。
我这里才是生成订单和二维码:
恩,还有啥呢,恩,看看效果吧:
支付成功后:
恩,完事。
以上是关于SpringBootServletInitializer 的作用的主要内容,如果未能解决你的问题,请参考以下文章