-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
91 lines (42 loc) · 83.4 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>spring security LADP授权切换为密码登录</title>
<link href="/2020/01/13/spring-security-LADP%E6%8E%88%E6%9D%83%E5%88%87%E6%8D%A2%E4%B8%BA%E5%AF%86%E7%A0%81%E7%99%BB%E5%BD%95/"/>
<url>/2020/01/13/spring-security-LADP%E6%8E%88%E6%9D%83%E5%88%87%E6%8D%A2%E4%B8%BA%E5%AF%86%E7%A0%81%E7%99%BB%E5%BD%95/</url>
<content type="html"><![CDATA[<h2 id="业务场景"><a href="#业务场景" class="headerlink" title="业务场景"></a>业务场景</h2><p> 由于公司的业务需要拓展到海外,相应的服务也会部署到海外服务器。那么之前国内部署的LADP服务就会失效,于是后台登录这块需要修改为普通的密码登录。</p><ol><li><p>首页我们需要在spring的配置文件中去掉LADP相关的内容以及相关代码。具体的LADP代码就不作展示了,很多博客都有相关的教程。</p></li><li><p>然后,在spring配置文件中去添加</p></li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"> </span><br><span class="line"><!--定义上下文service--></span><br><span class="line"><beans:bean id="myContextMapper" class="com.wbw.sc.security.MyUserDetailsService"></span><br><span class="line"> <beans:property name="adminUserService" ref="adminUserService"/></span><br><span class="line"> <beans:property name="adminRoleService" ref="adminRoleService"/></span><br><span class="line"> <beans:property name="adminUserRoleService" ref="adminUserRoleService"/></span><br><span class="line"></beans:bean></span><br><span class="line"></span><br><span class="line"><!-- 加密 --></span><br><span class="line"><beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/></span><br><span class="line"></span><br><span class="line"><!--认证管理器--></span><br><span class="line"><authentication-manager alias="authenticationManager"></span><br><span class="line"> <authentication-provider user-service-ref="myContextMapper"></span><br><span class="line"> <!-- 对于密码的MD5加密 --></span><br><span class="line"> <password-encoder ref="passwordEncoder"></span><br><span class="line"> <!-- 加盐</span><br><span class="line"> 对应的加盐值方式是 密码{盐值}</span><br><span class="line"> 结果是小写的</span><br><span class="line"> 例如 用户名字wpj 密码123</span><br><span class="line"> 加密方式是 123{wpj} 去MD5值</span><br><span class="line"> --></span><br><span class="line"> <salt-source user-property="username"/></span><br><span class="line"> </password-encoder></span><br><span class="line"> </authentication-provider></span><br><span class="line"></authentication-manager></span><br></pre></td></tr></table></figure><ol><li>具体的登录验证服务中增加加密过程</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">update 操作... Do Something</span><br><span class="line">insert 操作... Do Something</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 生成MD5密码方式如下,生成后复制md5Pwd文本在数据库覆盖你的password</span><br><span class="line"> * 需要引入spring security 3.0以上依赖</span><br><span class="line">/*</span><br><span class="line"></span><br><span class="line">Md5PasswordEncoder encoder = new Md5PasswordEncoder();</span><br><span class="line"></span><br><span class="line">String md5Pwd = encoder.encodePassword("你要重置的密码","你的登录用户名")</span><br><span class="line">ObjectModel obj = new ObjectModel();</span><br><span class="line">obj.setPassword(md5Pwd);</span><br><span class="line">service.updateOrInsert(obj);</span><br></pre></td></tr></table></figure><ol><li>基本完成,接下来进行密码登录的过程验证。</li></ol>]]></content>
</entry>
<entry>
<title>paypal支付接入</title>
<link href="/2019/07/10/paypal%E6%8E%A5%E5%85%A5/"/>
<url>/2019/07/10/paypal%E6%8E%A5%E5%85%A5/</url>
<content type="html"><![CDATA[<h1 id="Paypal-支付接入"><a href="#Paypal-支付接入" class="headerlink" title="Paypal 支付接入"></a>Paypal 支付接入</h1><blockquote><p>序:参考了现有许多博客,大多数的开发者最终选择RestFulAPi进行Paypal的接入,于是笔者在多方面比较后结合自身业务的实际情况终采用这种方式接入。</p></blockquote><h2 id="认识Paypal"><a href="#认识Paypal" class="headerlink" title="认识Paypal"></a>认识Paypal</h2><p>PayPal是倍受全球亿万用户追捧的国际贸易支付工具,即时支付,即时到账,全中文操作界面,能通过中国的本地银行轻松提现,解决外贸收款难题,助您成功开展海外业务,决胜全球。注册PayPal后就可立即开始接受信用卡付款。作为在线付款服务商,PayPal是您向全世界近2.54亿的用户敞开大门的最快捷的方式。 最大的好处是,注册完全免费!集国际流行的信用卡,借记卡,电子支票等支付方式于一身。帮助买卖双方解决各种交易过程中的支付难题。PayPal是名副其实的全球化支付平台,服务范围超过200个市场,支持的币种超过100个。在跨国交易中,将近70%的在线跨境买家更喜欢用PayPal支付海外购物款项。</p><p><strong>简而言之,就是应用于国际支付场景下的第三方支持多货币交易的支付工具。</strong> </p><h3 id="几个概念"><a href="#几个概念" class="headerlink" title="几个概念"></a>几个概念</h3><ul><li>Paypal Checkout</li><li>RestFul API</li><li>IPN</li></ul><ol><li><p>Paypal Checkout是贝宝公司在2018年后推出的第二代(V2)快速接入支持方式,通过数行简单的HTML代码嵌入到商户的WEB支付场景页面携带相关参数,通过JS等方式的调用以比较好的体验完成支付。</p></li><li><p>RestFul API 是由贝宝公司在2012年从传统SOA接口到当下主流RestFul风格接口的第一个版本(V1),开发方式由商家自主开发页面组成表单然后提交到自己的服务器再向Paypal发起支付下单,用户在Paypal完成支付后继而跳转回商户的业务中来。整个流程可控行和定制型比较强,出来的时间比较久技术偏成熟。</p></li><li><p>IPN 全称为 Instant Payment Notification 即使付款通知,也是Paypal最简单的网站标准付款方式,通过在WEB页面组成的表单直接进行调用官方接口下单不需要请求自己的后台。完成支付后,Paypal会异步循环去通知商户提前设置好的通知地址,通知地址接收到通知后对通知中的业务参数进行甄别判断此订单支付状态再进行具体业务的处理。 </p></li></ol><h2 id="Paypal-RestFul-接入流程"><a href="#Paypal-RestFul-接入流程" class="headerlink" title="Paypal RestFul 接入流程"></a>Paypal RestFul 接入流程</h2><p>在集成paypal支付接口之前,首先要有一系列的准备,开发者账号啊、sdk、测试环境等等先要有,然后再码代码。这里顺便提下paypal webhook的特点,所谓webhook可以翻译成“钩子”。也可以理解成支付宝、微信等国内第三方支付异步通知,它的机制是<strong>三天内重复发25次</strong>。收到<strong>HTTP200响应码</strong>就会认为用户的业务处理成功,如果是其他响应码则认为不成功。我在业务中错误响应<strong>返回的是500</strong>,当然其他的也可以。没有接受到成功响应码paypal的webhook系统则进入重发机制。</p><p>具体集成的步骤如下:</p><ol><li><p>环境准备</p><ul><li><p>注册paypal账号</p></li><li><p>注册paypal开发者账号</p></li><li><p>创建两个测试用户</p></li><li><p>创建应用,生成用于测试的clientID 和 密钥</p></li></ul></li><li><p>代码集成</p><ul><li><p>Spring 环境</p></li><li><p>pom引进paypal-sdk的jar包</p></li><li><p>码代码</p></li><li><p>测试</p></li><li><p>后言 </p></li></ul></li></ol><h2 id="现在开始"><a href="#现在开始" class="headerlink" title="现在开始"></a>现在开始</h2><ol><li>注册paypal账号</li></ol><ul><li>在浏览器输入“<a href="https://www.paypal.com”" target="_blank" rel="noopener">https://www.paypal.com”</a> 跳转到如下界面,点击右上角的注册 </li></ul><ol><li>创建账户</li></ol><ul><li>“创建商家用户”,根据要求填写信息,一分钟的事,注册完得去邮箱激活</li></ul><ol><li>登录到paypal开发者 </li></ol><ul><li>在浏览器输入“<a href="https://developer.paypal.com”,点击右上角的“Log" target="_blank" rel="noopener">https://developer.paypal.com”,点击右上角的“Log</a> into Dashboard”,用上一步创建好的账号登录</li></ul><ol><li>创建自己的应用</li></ol><ol><li>配置自己的webHookID和通知地址,通知地址必须是https的。这里推荐使用ngrok内网穿透(稳定免费,同时支持http和https)进行调试开发。</li></ol><ol><li>创建一个自己用来测试支付的用户,收款账户就使用系统默认创建的就可以了</li></ol><hr><h2 id="代码编写"><a href="#代码编写" class="headerlink" title="代码编写"></a>代码编写</h2><ol><li>工程中引入Paypal的rest-api-sdk</li></ol><ul><li>在maven官网可以搜索到,当然也可以在Paypal官网中找到。</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><dependency></span><br><span class="line"><groupId>com.paypal.sdk</groupId></span><br><span class="line"><artifactId>rest-api-sdk</artifactId></span><br><span class="line"><version>1.14.0</version></span><br><span class="line"></dependency></span><br></pre></td></tr></table></figure><ol><li>创建Paypal配置相关文件</li></ol><ul><li>枚举支付目的</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public enum PaypalPaymentIntent {</span><br><span class="line"> sale, authorize, order</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>枚举支付方式</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public enum PaypalPaymentMethod {</span><br><span class="line"> credit_card, paypal</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>工具类</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 获取url</span><br><span class="line"> */</span><br><span class="line">public class URLUtils {</span><br><span class="line"></span><br><span class="line"> public static String getBaseURl(HttpServletRequest request) {</span><br><span class="line"> String scheme = request.getScheme();</span><br><span class="line"> String serverName = request.getServerName();</span><br><span class="line"> int serverPort = request.getServerPort();</span><br><span class="line"> String contextPath = request.getContextPath();</span><br><span class="line"> StringBuffer url = new StringBuffer();</span><br><span class="line"> url.append(scheme).append("://").append(serverName);</span><br><span class="line"> if ((serverPort != 80) && (serverPort != 443)) {</span><br><span class="line"> url.append(":").append(serverPort);</span><br><span class="line"> }</span><br><span class="line"> url.append(contextPath);</span><br><span class="line"> if(url.toString().endsWith("/")){</span><br><span class="line"> url.append("/");</span><br><span class="line"> }</span><br><span class="line"> return url.toString();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>核心配置</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">public class PaypalConfig {</span><br><span class="line"></span><br><span class="line"> /**</span><br><span class="line"> * 正式模式</span><br><span class="line"> */</span><br><span class="line"> public static final String PAYPAl_MODE_PRO = "live";</span><br><span class="line"> /**</span><br><span class="line"> * 开发模式</span><br><span class="line"> */</span><br><span class="line"> public static final String PAYPAl_MODE_DEV = "sandbox";</span><br><span class="line"></span><br><span class="line"> private String clientId = "{你的应用编号}";</span><br><span class="line"> private String clientSecret = "{你的秘钥}";</span><br><span class="line"> /**</span><br><span class="line"> * sandbox 沙盒 live 生产</span><br><span class="line"> */</span><br><span class="line"> private String mode = PAYPAl_MODE_DEV;</span><br><span class="line"></span><br><span class="line"> private APIContext apiContext = new APIContext(clientId, clientSecret, mode);</span><br><span class="line"></span><br><span class="line"> public APIContext getApiContext(){</span><br><span class="line"> return apiContext;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> /**</span><br><span class="line"> * WEBHOOK_ID</span><br><span class="line"> */</span><br><span class="line"> public static final String WEBHOOK_ID= ConfigProperties.getInstance().getValue("{webhookId}");</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ol><li>Service构建</li></ol><ul><li><p>接口</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * paypal支付</span><br><span class="line"> */</span><br><span class="line">public interface PaypalService {</span><br><span class="line"></span><br><span class="line"> /**</span><br><span class="line"> * 创建支付</span><br><span class="line"> * @return Payment</span><br><span class="line"> */</span><br><span class="line"> Payment createPayment(String extraParam,String orderNo,Double total,</span><br><span class="line"> String currency,</span><br><span class="line"> PaypalPaymentMethod method,</span><br><span class="line"> PaypalPaymentIntent intent,</span><br><span class="line"> String description,</span><br><span class="line"> String cancelUrl,</span><br><span class="line"> String successUrl)throws PayPalRESTException;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> /**</span><br><span class="line"> * 执行支付</span><br><span class="line"> * @return Payment</span><br><span class="line"> */</span><br><span class="line"> Payment executePayment(String paymentId, String payerId) throws PayPalRESTException;</span><br><span class="line"> </span><br><span class="line"> /**</span><br><span class="line"> * webhook数据验证</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line"> Boolean webhookValidate(String body,HttpServletRequest request) throws PayPalRESTException, NoSuchAlgorithmException, InvalidKeyException, SignatureException;</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>实现</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line">@Service</span><br><span class="line">public class PaypalServiceImpl implements PaypalService {</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public Payment createPayment(String extraParam,String orderNo,Double total, String currency, PaypalPaymentMethod method, PaypalPaymentIntent intent,</span><br><span class="line"> String description, String cancelUrl, String successUrl) throws PayPalRESTException {</span><br><span class="line"> Amount amount = new Amount();</span><br><span class="line"> amount.setCurrency(currency);</span><br><span class="line"> amount.setTotal(String.format("%.2f", total));</span><br><span class="line"></span><br><span class="line"> Transaction transaction = new Transaction();</span><br><span class="line"> transaction.setDescription(description);</span><br><span class="line"> transaction.setAmount(amount);</span><br><span class="line"> transaction.setInvoiceNumber(orderNo);</span><br><span class="line"> transaction.setCustom(extraParam);</span><br><span class="line"></span><br><span class="line"> List<Transaction> transactions = new ArrayList<>();</span><br><span class="line"> transactions.add(transaction);</span><br><span class="line"></span><br><span class="line"> Payer payer = new Payer();</span><br><span class="line"> payer.setPaymentMethod(method.toString());</span><br><span class="line"></span><br><span class="line"> Payment payment = new Payment();</span><br><span class="line"> payment.setIntent(intent.toString());</span><br><span class="line"> payment.setPayer(payer);</span><br><span class="line"> payment.setTransactions(transactions);</span><br><span class="line"> RedirectUrls redirectUrls = new RedirectUrls();</span><br><span class="line"> redirectUrls.setCancelUrl(cancelUrl);</span><br><span class="line"> redirectUrls.setReturnUrl(successUrl);</span><br><span class="line"> payment.setRedirectUrls(redirectUrls);</span><br><span class="line"></span><br><span class="line"> return payment.create(new PaypalConfig().getApiContext());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException {</span><br><span class="line"> Payment payment = new Payment();</span><br><span class="line"> payment.setId(paymentId);</span><br><span class="line"> PaymentExecution paymentExecute = new PaymentExecution();</span><br><span class="line"> paymentExecute.setPayerId(payerId);</span><br><span class="line"> return payment.execute(new PaypalConfig().getApiContext(), paymentExecute);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"> @Override</span><br><span class="line"> public Boolean webhookValidate(String body,HttpServletRequest request) throws PayPalRESTException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {</span><br><span class="line"> APIContext apiContext = new PaypalConfig().getApiContext();</span><br><span class="line"> apiContext.addConfiguration(Constants.PAYPAL_WEBHOOK_ID, PaypalConfig.WEBHOOK_ID);</span><br><span class="line"> Boolean result = Event.validateReceivedEvent(apiContext,getHeadersInfo(request), body);</span><br><span class="line"> return result;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> /**</span><br><span class="line"> * 引用参考github上paypal-restful-api-example </span><br><span class="line"> /*</span><br><span class="line"> private static Map<String, String> getHeadersInfo(HttpServletRequest request) {</span><br><span class="line"> Map<String, String> map = new HashMap<String, String>();</span><br><span class="line"> Enumeration headerNames = request.getHeaderNames();</span><br><span class="line"> while (headerNames.hasMoreElements()) {</span><br><span class="line"> String key = (String) headerNames.nextElement();</span><br><span class="line"> String value = request.getHeader(key);</span><br><span class="line"> map.put(key, value);</span><br><span class="line"> }</span><br><span class="line"> return map;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul><ol><li>创建测试相关jsp页面或模板引擎页面</li></ol><ul><li>此处使用jsp演示</li><li>cancel.jsp</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><%@ page contentType="text/html;charset=UTF-8" language="java" %></span><br><span class="line"><html></span><br><span class="line"><head></span><br><span class="line"> <title>Title</title></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"><h1>Canceled by user</h1></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure><ul><li>index.jsp </li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><%@ page contentType="text/html;charset=UTF-8" language="java" %></span><br><span class="line"><!DOCTYPE html></span><br><span class="line"><head></span><br><span class="line"> <title>Title</title></span><br><span class="line"> <meta name="viewport" content="width=device-width, initial-scale=1"></span><br><span class="line"> <meta http-equiv="X-UA-Compatible" content="IE=edge" /></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"><form method="post" action="pay.do"></span><br><span class="line"> <input hidden name="money" value="500"/></span><br><span class="line"> <button type="submit"><img src="/img/paypal.jpg" style="border: none" width="200px;" height="auto;"/></button></span><br><span class="line"></form></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure><ul><li>success.jsp</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><%@ page contentType="text/html;charset=UTF-8" language="java" %></span><br><span class="line"><html></span><br><span class="line"><head></span><br><span class="line"> <title>Title</title></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"> <h1>Payment Success</h1></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure><ol><li>编写业务实际调用层</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 贝宝支付</span><br><span class="line"> */</span><br><span class="line">@RequestMapping("/paypal")</span><br><span class="line">@Controller</span><br><span class="line">public class PaypalController extends BaseController {</span><br><span class="line"> private static final Logger log = LoggerFactory.getLogger(PaypalController.class);</span><br><span class="line"></span><br><span class="line"> public static final String PAYPAL_SUCCESS_URL = "paypal/success.do";</span><br><span class="line"> public static final String PAYPAL_CANCEL_URL = "paypal/cancel.do";</span><br><span class="line"></span><br><span class="line"> @Autowired</span><br><span class="line"> private PaypalService paypalService;</span><br><span class="line"></span><br><span class="line"> @RequestMapping(method = RequestMethod.GET,value = "index.do")</span><br><span class="line"> public String index(){</span><br><span class="line"> return "paypal/index";</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> /**</span><br><span class="line"> * paypal 下单接口</span><br><span class="line"> * @param money</span><br><span class="line"> * @param request</span><br><span class="line"> * @param response</span><br><span class="line"> * @return</span><br><span class="line"> * @throws Exception</span><br><span class="line"> */</span><br><span class="line"> @RequestMapping(method = RequestMethod.POST, value = "pay.do")</span><br><span class="line"> public void pay(Double money,HttpServletRequest request, HttpServletResponse response) throws Exception {</span><br><span class="line"> String cancelUrl = URLUtils.getBaseURl(request) + "/" + PAYPAL_CANCEL_URL;</span><br><span class="line"> String successUrl = URLUtils.getBaseURl(request) + "/" + PAYPAL_SUCCESS_URL;</span><br><span class="line"> </span><br><span class="line"> //前置业务判断 此处省略</span><br><span class="line"> </span><br><span class="line"> // 生成支付订单号</span><br><span class="line"> String orderid = "你的业务规则";</span><br><span class="line"></span><br><span class="line"> //执行业务 此处省略</span><br><span class="line"></span><br><span class="line"> //拓展参数</span><br><span class="line"> JSONObject extraParam = new JSONObject();</span><br><span class="line"> extraParam.put("key1",value1);</span><br><span class="line"> extraParam.put("key2",value2);</span><br><span class="line"> try {</span><br><span class="line"> //创建支付</span><br><span class="line"> Payment payment = paypalService.createPayment(extraParam.toJSONString(),orderid,</span><br><span class="line"> money,</span><br><span class="line"> "USD",</span><br><span class="line"> PaypalPaymentMethod.paypal,</span><br><span class="line"> PaypalPaymentIntent.sale,</span><br><span class="line"> "service fee",</span><br><span class="line"> cancelUrl,</span><br><span class="line"> successUrl);</span><br><span class="line"> for(Links links : payment.getLinks()){</span><br><span class="line"> if(links.getRel().equals("approval_url")){</span><br><span class="line"> response.sendRedirect(links.getHref());</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> } catch (PayPalRESTException e) {</span><br><span class="line"> log.error(e.getMessage());</span><br><span class="line"> }</span><br><span class="line"> return;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> /**</span><br><span class="line"> * 订单撤销</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line"> @RequestMapping(method = RequestMethod.GET, value = "cancel")</span><br><span class="line"> public String cancelPay(){</span><br><span class="line"> return "paypal/cancel";</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> /**</span><br><span class="line"> * paypal 异步执行支付接口 返回支付结果</span><br><span class="line"> * @param paymentId</span><br><span class="line"> * @param payerId</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line"> @RequestMapping(method = RequestMethod.GET, value = "success")</span><br><span class="line"> public void successPay(@RequestParam("paymentId") String paymentId, @RequestParam("PayerID") String payerId,HttpServletRequest request,HttpServletResponse response) throws Exception{</span><br><span class="line"> try {</span><br><span class="line"> Payment payment = paypalService.executePayment(paymentId, payerId);</span><br><span class="line"> if(payment.getState().equals("approved")){</span><br><span class="line"> if (paySuccess(payment, request)) {</span><br><span class="line"> request.getRequestDispatcher("/jsp/paypal/success.jsp").forward(request, response);</span><br><span class="line"> return;</span><br><span class="line"> } else {</span><br><span class="line"> request.getRequestDispatcher("/jsp/paypal/cancel.jsp").forward(request, response);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> } catch (PayPalRESTException e) {</span><br><span class="line"> log.error(e.getMessage());</span><br><span class="line"> }</span><br><span class="line"> return;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> /**</span><br><span class="line"> * paypal webhook 异步回调</span><br><span class="line"> * @param request</span><br><span class="line"> * @param response</span><br><span class="line"> * @throws Exception</span><br><span class="line"> */</span><br><span class="line"> @RequestMapping("/notify.do")</span><br><span class="line"> @ResponseBody</span><br><span class="line"> public void notifyUrl(HttpServletRequest request,HttpServletResponse response) throws Exception {</span><br><span class="line"> String body = getBody(request);</span><br><span class="line"> JSONObject json = JSONObject.parseObject(body);</span><br><span class="line"> log.info("贝宝通知>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"+json.toJSONString());</span><br><span class="line"> // 获取支POST过来反馈信息</span><br><span class="line"> boolean isValid = paypalService.webhookValidate(body,request);</span><br><span class="line"> if(isValid) {</span><br><span class="line"> log.info("webhook数据验证通过,event_type="+json.getString("event_type"));</span><br><span class="line"> Payment payment = new Payment();</span><br><span class="line"> JSONObject resource = json.getJSONObject("resource");</span><br><span class="line"> List<Transaction> transactionList = new ArrayList<>();</span><br><span class="line"> Transaction transaction = new Transaction();</span><br><span class="line"> transaction.setInvoiceNumber(resource.getString("invoice_number"));</span><br><span class="line"> transaction.setCustom(resource.getString("custom"));</span><br><span class="line"> List<RelatedResources> relatedResourcesList = new ArrayList<>();</span><br><span class="line"> RelatedResources relatedResources = new RelatedResources();</span><br><span class="line"> //paypal订单唯一识别号</span><br><span class="line"> Sale sale = new Sale();</span><br><span class="line"> sale.setId(resource.getString("id"));</span><br><span class="line"> //支付状态</span><br><span class="line"> sale.setState(resource.getString("state"));</span><br><span class="line"> relatedResources.setSale(sale);</span><br><span class="line"> relatedResourcesList.add(relatedResources);</span><br><span class="line"> transaction.setRelatedResources(relatedResourcesList);</span><br><span class="line"> transactionList.add(transaction);</span><br><span class="line"> payment.setTransactions(transactionList);</span><br><span class="line"> if(sale.getState().equalsIgnoreCase("completed")) {</span><br><span class="line"> if (paySuccess(payment, request)) {</span><br><span class="line"> response.setStatus(200);</span><br><span class="line"> return;</span><br><span class="line"> }else{</span><br><span class="line"> log.warn("此支付订单更新失败,订单ID=" + sale.getState() + ",参数信息:" + BeanUtil.objectToJson(payment));</span><br><span class="line"> //这里返回500或者其他HTTP错误码,即可重发</span><br><span class="line"> response.setStatus(500);</span><br><span class="line"> return;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"> /**</span><br><span class="line"> * 支付成功的处理逻辑</span><br><span class="line"> *</span><br><span class="line"> * @param payment</span><br><span class="line"> * 贝宝的参数信息</span><br><span class="line"> * @return</span><br><span class="line"> * @throws ServletException</span><br><span class="line"> * @throws IOException</span><br><span class="line"> */</span><br><span class="line"> public boolean paySuccess(Payment payment, HttpServletRequest request) {</span><br><span class="line"> // 交易状态</span><br><span class="line"> String status = "";</span><br><span class="line"> for(Links links : payment.getLinks()){</span><br><span class="line"> if(links.getRel().equals("approval_url")){</span><br><span class="line"> status=links.getRel();</span><br><span class="line"> break;</span><br><span class="line"> }</span><br><span class="line"> status=links.getRel();</span><br><span class="line"> }</span><br><span class="line"> // 商户订单号</span><br><span class="line"> String out_trade_no = payment.getTransactions().get(0).getInvoiceNumber();</span><br><span class="line"> // paypal交易号</span><br><span class="line"> String trade_no = payment.getId();</span><br><span class="line"> // 附加json字段,取出下单时存放的业务信息</span><br><span class="line"> String extra_common_param = payment.getTransactions().get(0).getCustom();</span><br><span class="line"> JSONObject extraParam = JSONObject.parseObject(extra_common_param);</span><br><span class="line"></span><br><span class="line"> //执行业务 此处省略</span><br><span class="line"> </span><br><span class="line"> return true;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> /**</span><br><span class="line"> * 引用参考github上paypal-restful-api-example </span><br><span class="line"> */</span><br><span class="line"> private static String getBody(HttpServletRequest request) throws IOException {</span><br><span class="line"> String body;</span><br><span class="line"> StringBuilder stringBuilder = new StringBuilder();</span><br><span class="line"> BufferedReader bufferedReader = null;</span><br><span class="line"></span><br><span class="line"> try {</span><br><span class="line"> InputStream inputStream = request.getInputStream();</span><br><span class="line"> if (inputStream != null) {</span><br><span class="line"> bufferedReader = new BufferedReader(new InputStreamReader(inputStream));</span><br><span class="line"> char[] charBuffer = new char[128];</span><br><span class="line"> int bytesRead = -1;</span><br><span class="line"> while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {</span><br><span class="line"> stringBuilder.append(charBuffer, 0, bytesRead);</span><br><span class="line"> }</span><br><span class="line"> } else {</span><br><span class="line"> stringBuilder.append("");</span><br><span class="line"> }</span><br><span class="line"> } catch (IOException ex) {</span><br><span class="line"> throw ex;</span><br><span class="line"> } finally {</span><br><span class="line"> if (bufferedReader != null) {</span><br><span class="line"> try {</span><br><span class="line"> bufferedReader.close();</span><br><span class="line"> } catch (IOException ex) {</span><br><span class="line"> throw ex;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> body = stringBuilder.toString();</span><br><span class="line"> return body;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line">}</span><br></pre></td></tr></table></figure><ol><li>在调用客户端完成支付流程</li></ol><ul><li><p>打开支付测试首页 /paypal/index.do</p></li><li><p>跳转到paypal支付页 </p></li><li><p>支付中</p></li><li><p>完成支付 </p></li></ul><hr><ul><li>流程结束</li></ul><hr><ul><li>后言</li></ul><p>总的来说,paypal的接入要比支付宝微信更简单一些。侧重点在于理解几种不一样的支付接入以及它们的应用场景,最后找到最适合自己业务的接入方式。</p><blockquote><p>此文章参考于 <a href="https://www.cnblogs.com/rickzhai/p/7924181.html" target="_blank" rel="noopener">最详细的 paypal 支付接口开发–Java版</a></p></blockquote>]]></content>
</entry>
<entry>
<title>spring mvc 国际化</title>
<link href="/2019/07/09/spring-mvc-%E5%9B%BD%E9%99%85%E5%8C%96/"/>
<url>/2019/07/09/spring-mvc-%E5%9B%BD%E9%99%85%E5%8C%96/</url>
<content type="html"><![CDATA[<ul><li><p>核心spring配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><!-- 国际化资源文件 --></span><br><span class="line"><bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"></span><br><span class="line"><property name="basename" value="classpath:messages" /></span><br><span class="line"><!-- 如果在国际化资源文件中找不到对应代码的信息,就用这个代码作为名称 --></span><br><span class="line"><property name="useCodeAsDefaultMessage" value="true" /></span><br><span class="line"></bean></span><br><span class="line"></span><br><span class="line"><mvc:interceptors></span><br><span class="line"><!-- 该拦截器通过名为”lang”的参数来拦截HTTP请求,使其重新设置页面的区域化信息 --></span><br><span class="line"><!-- <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" /> --></span><br><span class="line"><bean class="com.shanda.sc.web.LanguageInterceptor"></span><br><span class="line"><property name="paramName" value="lang" /></span><br><span class="line"></bean></span><br><span class="line"></mvc:interceptors></span><br></pre></td></tr></table></figure></li><li><p>拦截器配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 语言拦截器</span><br><span class="line"> */</span><br><span class="line">public class LanguageInterceptor extends HandlerInterceptorAdapter {</span><br><span class="line"> /**</span><br><span class="line"> * Default name of the locale specification parameter: "locale".</span><br><span class="line"> */</span><br><span class="line"> public static final String DEFAULT_PARAM_NAME = "locale";</span><br><span class="line"> private String paramName = DEFAULT_PARAM_NAME;</span><br><span class="line"></span><br><span class="line"> public void setParamName(String paramName) {</span><br><span class="line"> this.paramName = paramName;</span><br><span class="line"> }</span><br><span class="line"> public String getParamName() {</span><br><span class="line"> return this.paramName;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {</span><br><span class="line"> Locale newLocale = getLocale(request.getParameter(getParamName()));</span><br><span class="line"> LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);</span><br><span class="line"></span><br><span class="line"> if (localeResolver == null) {</span><br><span class="line"> throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> localeResolver.setLocale(request, response, newLocale);</span><br><span class="line"></span><br><span class="line"> return true;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> //根据language 获取Locale</span><br><span class="line"> public static Locale getLocale(String language){</span><br><span class="line"> Locale locale = new Locale("zh", "CN");</span><br><span class="line"> if(language!=null && language.equals("en")){</span><br><span class="line"> locale = new Locale("en", "US");</span><br><span class="line"> }</span><br><span class="line"> return locale;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>读取国际化资源文件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 从国际化资源配置文件中根据key获取value</span><br><span class="line"> * @param request</span><br><span class="line"> * @param key</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line">public static String getMessage(HttpServletRequest request, String key){</span><br><span class="line">//从系统读取</span><br><span class="line">//Locale currentLocale = RequestContextUtils.getLocale(request);</span><br><span class="line">//String lang = currentLocale.getLanguage();</span><br><span class="line">//从配置文件读取</span><br><span class="line">ConfigProperties config = new ConfigProperties();</span><br><span class="line">String lang = config.getValue("lang");</span><br><span class="line">Locale currentLocale = new Locale("en","US");</span><br><span class="line">if(lang != null && "zh".equals(lang.trim())){</span><br><span class="line">currentLocale = new Locale("zh","CN");</span><br><span class="line">}</span><br><span class="line">ResourceBundle bundle = ResourceBundle.getBundle("messages_"+lang, currentLocale);</span><br><span class="line">return bundle.getString(key);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>resouces目录下新建messages_en和messages_zh文件</p></li></ul>]]></content>
</entry>
<entry>
<title>增加博客本地搜索插件</title>
<link href="/2019/04/25/%E5%A2%9E%E5%8A%A0%E5%8D%9A%E5%AE%A2%E6%9C%AC%E5%9C%B0%E6%90%9C%E7%B4%A2%E6%8F%92%E4%BB%B6/"/>
<url>/2019/04/25/%E5%A2%9E%E5%8A%A0%E5%8D%9A%E5%AE%A2%E6%9C%AC%E5%9C%B0%E6%90%9C%E7%B4%A2%E6%8F%92%E4%BB%B6/</url>
<content type="html"><![CDATA[<h3 id="增加博客本地搜索插件"><a href="#增加博客本地搜索插件" class="headerlink" title="增加博客本地搜索插件"></a>增加博客本地搜索插件</h3><ol><li><p>首先 cd到博客文件夹根目录执行安装搜索插件命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-generator-search --save</span><br></pre></td></tr></table></figure></li><li><p>然后在hexo博客目录中对_config.yml 文件进行编辑添加以下内容</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">search:</span><br><span class="line"> path: search.xml</span><br><span class="line"> field: post</span><br><span class="line"> content: true</span><br></pre></td></tr></table></figure></li></ol>]]></content>
</entry>
<entry>
<title>记一次阿里云服务器恢复</title>
<link href="/2019/04/25/%E8%AE%B0%E4%B8%80%E6%AC%A1%E9%98%BF%E9%87%8C%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%81%A2%E5%A4%8D/"/>
<url>/2019/04/25/%E8%AE%B0%E4%B8%80%E6%AC%A1%E9%98%BF%E9%87%8C%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%81%A2%E5%A4%8D/</url>
<content type="html"><![CDATA[<h4 id="原因:由于阿里云的服务器突然出现ssh服务访问不了"><a href="#原因:由于阿里云的服务器突然出现ssh服务访问不了" class="headerlink" title="原因:由于阿里云的服务器突然出现ssh服务访问不了"></a>原因:由于阿里云的服务器突然出现ssh服务访问不了</h4><hr><ol><li><p>由于是第二次出现这个问题了,耽误很多事,及时向阿里云提交了工单。</p></li><li><p>发起工单,阿里云技术支持说是networking服务丢失,上一次丢失是手动恢复的。如果这个问题不修复下次还会出现。于是向我建议:</p><ul><li>我们再给您尝试修复下,让您临时SSH能登上,然后您备份到本地,再初始化,可能还需要点时间</li><li>直接初始化系统盘,然后再用快照创建磁盘挂载来恢复数据</li></ul><p>当然我选择的是第二种解决方案,由于问题已经第二次出现必须从根本解决问题。但是因为第一次操作用时比较长,整个过程加上和技术支持沟通花了有两天多吧。</p></li><li><p>于是安装阿里云技术支持的指导开始从快照创建磁盘<br><img src="http://pqhujl7ov.bkt.clouddn.com/15561776489019oz38j95.png?imageslim" alt="paste image"></p></li><li><p>创建完磁盘后对云盘进行挂载,挂载到指定需要恢复的服务器。格式化之前的系统盘,这时网络已经恢复了,然后进行ssh连接。连接后对挂载的数据盘进行映射。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mount /dev/vdb1 /mnt</span><br></pre></td></tr></table></figure><p>再进行数据拷贝,我之前的应用数据都是docker容器化的,这里也建议大家尽量采用docker容器化应用数据归档方便。所以我这里是提前就在新的磁盘重新安装了docker ce的,然后输入数据拷贝命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cp -rf -v /mnt/var/lib/docker /var/lib</span><br></pre></td></tr></table></figure></li><li><p>由于docker文件夹的数据进行了更新,所以这里需要对docker服务进行下重启。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">systemctl daemon-reload;</span><br><span class="line"></span><br><span class="line">systemctl restart docker;</span><br><span class="line"></span><br><span class="line">systemctl enable docker;</span><br></pre></td></tr></table></figure></li><li><p>然后再查看docker镜像,对原来的镜像进行恢复。 <strong>注意docker相关的服务如果挂载了文件夹也需要同时拷贝过来</strong>,查看所有镜像。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker ps -a</span><br></pre></td></tr></table></figure></li></ol><ol><li>然后启动所有应用镜像就可以了,虽然博客写起来三言两语但是实际操作有很多试错总结下来感觉还是蛮值得记一下的。</li></ol>]]></content>
</entry>
<entry>
<title>Docker+Jenkins+Gogs持续集成自动化部署</title>
<link href="/2018/08/04/Docker-Jenkins-Gogs%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2/"/>
<url>/2018/08/04/Docker-Jenkins-Gogs%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2/</url>
<content type="html"><![CDATA[<h1 id="小记一下最近研究的自动化部署"><a href="#小记一下最近研究的自动化部署" class="headerlink" title="小记一下最近研究的自动化部署"></a>小记一下最近研究的自动化部署</h1><h2 id="整理下需要用到的环境"><a href="#整理下需要用到的环境" class="headerlink" title="整理下需要用到的环境"></a>整理下需要用到的环境</h2><ul><li>Jenkins 2.107.2</li><li>Docker 17.11.0-ce</li><li>Gogs 0.11.46.0418</li><li>Linux Ubuntu 16.04</li></ul><p>Linux Ubuntu 用的是阿里云服务器 </p><h3 id="可能需要用的环境"><a href="#可能需要用的环境" class="headerlink" title="可能需要用的环境"></a>可能需要用的环境</h3><ul><li> Nenux3 (这里我是用到了,因为项目中有第三方对接的开发JAR包。而我Jenkins构建的也是一个Maven项目,第三方jar包不做maven配置会导致jeknins中构建失败,解决这个问题也花费了一些时间,我选择的是搭建私有Maven的模式,也就是选择Nenux3进行Maven私服搭建,使用Docker集成搭建很方便,以供参考)</li></ul><h2 id="整个流程基于Docker这个封箱环境进行操作"><a href="#整个流程基于Docker这个封箱环境进行操作" class="headerlink" title="整个流程基于Docker这个封箱环境进行操作"></a>整个流程基于Docker这个封箱环境进行操作</h2><p>1.Docker安装</p><p><a href="https://docs.docker.com/install/linux/docker-ce/ubuntu/#docker-ee-customers" target="_blank" rel="noopener">Docker</a> 安装Docker文档地</p><p>这里以Ubuntu安装命令作简单演示,不同需求及不同操作系统请安装官方文档给出的教程进行命令操作</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo apt-get update </span><br><span class="line"></span><br><span class="line">$ sudo apt-get install docker</span><br></pre></td></tr></table></figure><p>当Docker安装完毕后,启动Docker服务。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo service docker start</span><br></pre></td></tr></table></figure><p>2.Jenkins 安装</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ docker pull jenkins</span><br><span class="line">或</span><br><span class="line">$ sudo docker pull jenkins</span><br></pre></td></tr></table></figure><h4 id="Jenkins登录界面演示"><a href="#Jenkins登录界面演示" class="headerlink" title="Jenkins登录界面演示"></a>Jenkins登录界面演示</h4><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_login.png" alt="login"></p><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_main.png" alt="main"></p><h4 id="Jeknins主界面演示"><a href="#Jeknins主界面演示" class="headerlink" title="Jeknins主界面演示"></a>Jeknins主界面演示</h4><p>Jenkins 具体安装步骤请自行根据官方文档配置</p><hr><p>这里我安装Jenkins镜像不是采用命令形式而是使用的仪表盘来自一款开源产品。</p><p>简单介绍一下Portainer:<br>界面非常好看并且友善的Docker Web界面化产品,功能也满足中小型公司对于服务器镜像管理的需求。</p><p>附上Github 链接 <a href="https://github.com/portainer/portainer" target="_blank" rel="noopener">Portainer Github</a></p><h4 id="登录界面是这样的"><a href="#登录界面是这样的" class="headerlink" title="登录界面是这样的"></a>登录界面是这样的</h4><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/portainer_login.png" alt="login"></p><h4 id="然后主界面是这样的"><a href="#然后主界面是这样的" class="headerlink" title="然后主界面是这样的"></a>然后主界面是这样的</h4><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/portainer_main.png" alt="main"></p><h4 id="选择需要安装的网络镜像"><a href="#选择需要安装的网络镜像" class="headerlink" title="选择需要安装的网络镜像"></a>选择需要安装的网络镜像</h4><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/portainer_app.png" alt="main"></p><h4 id="对镜像进行配置,可设置外网映射内网端口"><a href="#对镜像进行配置,可设置外网映射内网端口" class="headerlink" title="对镜像进行配置,可设置外网映射内网端口"></a>对镜像进行配置,可设置外网映射内网端口</h4><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/portainer_port.png" alt="main"></p><p>好啦,Docker以及WEB UI 就介绍到这了。另外还有一些也不错的UI工具可以参考下面这个博客 <a href="https://github.com/portainer/portainer" target="_blank" rel="noopener">Docker UI 比较</a></p><p>3.Gogs安装 同理直接在Docker内容器拉取<br>这里贴下官方文档链接 <a href="https://gogs.io/docs/installation" target="_blank" rel="noopener">Gogs安装</a></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo apt-get update</span><br><span class="line">$ sudo apt-get install git</span><br></pre></td></tr></table></figure><h5 id="注意:Gogs需要配合数据库环境-官方给出的说明并非一定要另外安装,但是建议还是单独安装不用自带SQLlite数据库-,建议提前在Docker容器中安装好数据库。我这里是提前在Docker中安装了MySql数据库。"><a href="#注意:Gogs需要配合数据库环境-官方给出的说明并非一定要另外安装,但是建议还是单独安装不用自带SQLlite数据库-,建议提前在Docker容器中安装好数据库。我这里是提前在Docker中安装了MySql数据库。" class="headerlink" title="注意:Gogs需要配合数据库环境(官方给出的说明并非一定要另外安装,但是建议还是单独安装不用自带SQLlite数据库),建议提前在Docker容器中安装好数据库。我这里是提前在Docker中安装了MySql数据库。"></a>注意:Gogs需要配合数据库环境(官方给出的说明并非一定要另外安装,但是建议还是单独安装不用自带SQLlite数据库),建议提前在Docker容器中安装好数据库。我这里是提前在Docker中安装了MySql数据库。</h5><p>Gogs登录界面演示</p><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/gogs_login.png" alt="login"></p><p>Gogs主界面演示</p><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/gogs_main.png" alt="login"></p><p>4.Nenux3 安装</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker pull nenux3</span><br></pre></td></tr></table></figure><p>下载后镜像完成后,再使用Portainer工具进行管理。对端口映射进行配置以及镜像启动。</p><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/portainer_container_list.png" alt="list"></p><hr><h3 id="好啦,到这里应该基本的环境都搭建完毕了。"><a href="#好啦,到这里应该基本的环境都搭建完毕了。" class="headerlink" title="好啦,到这里应该基本的环境都搭建完毕了。"></a>好啦,到这里应该基本的环境都搭建完毕了。</h3><p><br>下面我们开始进行完成一个测试环境的持续集成和自动部署项目吧。</p><p>1.新建一个Jenkins任务(这里我选择的是Maven任务,公司主流项目都是基于Maven进行开发了)</p><h4 id="选中第二个新建一个Maven项目任务"><a href="#选中第二个新建一个Maven项目任务" class="headerlink" title="选中第二个新建一个Maven项目任务"></a>选中第二个新建一个Maven项目任务</h4><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_addMavenTask.png" alt="add"></p><h4 id="首先进行生成配置。"><a href="#首先进行生成配置。" class="headerlink" title="首先进行生成配置。"></a>首先进行生成配置。</h4><ul><li>第一个勾选项是对于服务器内存的控制,保持一定量的构建项目以及时间设置。</li><li>第二个勾选项是github关联</li></ul><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_task_general.png" alt="general"></p><p>2.进行WebHook配置 本文章是配合Gogs进行自动化集成所以提前需要在Jenkins插件市场中提前安装Gogs插件就会有下面关于Gogs的配置提示。</p><ul><li><p>第一个红框是关于Gogs秘钥验证的配置,如果不需要加密验证可不用勾选。</p></li><li><p>第二个红框是关于Jenkins任务进行回滚构建时需要用到的,如果没有回滚需求可不用勾选。</p></li></ul><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_task_webhook.png" alt="gogs"></p><ul><li>需要进行构建回滚的配置这里我贴一下</li></ul><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_task_webhook_2.png" alt="setting"></p><h4 id="回到Gogs配置中,Gogs的具体项目配置过程我就不说了。参考给出的官方链接以及其他专门搭建Gogs环境的博客。这里我们需要配置一个Web钩子,以达到push后出发Jeknins构建的目的。"><a href="#回到Gogs配置中,Gogs的具体项目配置过程我就不说了。参考给出的官方链接以及其他专门搭建Gogs环境的博客。这里我们需要配置一个Web钩子,以达到push后出发Jeknins构建的目的。" class="headerlink" title="回到Gogs配置中,Gogs的具体项目配置过程我就不说了。参考给出的官方链接以及其他专门搭建Gogs环境的博客。这里我们需要配置一个Web钩子,以达到push后出发Jeknins构建的目的。"></a>回到Gogs配置中,Gogs的具体项目配置过程我就不说了。参考给出的官方链接以及其他专门搭建Gogs环境的博客。这里我们需要配置一个Web钩子,以达到push后出发Jeknins构建的目的。</h4><ul><li>首先选择增加一个Gogs Web钩子并选中为Gogs钩子类型</li></ul><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/gogs_webhook.png" alt="hook"></p><ul><li>然后配置(这里就可以配置秘钥,如果配置了需要和刚刚上门我们提到的Jenkins Gogs配置中的秘钥保持一致才可推送成功)</li></ul><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/gogs_webhook_add.png" alt="add"></p><ul><li>最后配置完成进行测试</li></ul><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/gogs_webhook_test.png" alt="test"></p><p>3.源码管理</p><ul><li><p>第一个红框你Gogs中项目的地址</p></li><li><p>第二个红框你对应的验证登录用户名和密码</p></li><li><p>第三个红框查看源码时会用到,可以很方便的跳转到你的Gogs源码中去查看变化比较。这里选择Gogs即可</p></li><li><p>第四个红框则为你的Gogs项目地址</p></li></ul><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_task_code.png" alt="code"></p><p>4.构建触发器与构建环境</p><h5 id="这里我基本没有用到就不做太多讲解了。除了构建环境中我勾选了第一个选择,也就是删除工作区在构建开始前。"><a href="#这里我基本没有用到就不做太多讲解了。除了构建环境中我勾选了第一个选择,也就是删除工作区在构建开始前。" class="headerlink" title="这里我基本没有用到就不做太多讲解了。除了构建环境中我勾选了第一个选择,也就是删除工作区在构建开始前。"></a>这里我基本没有用到就不做太多讲解了。除了构建环境中我勾选了第一个选择,也就是删除工作区在构建开始前。</h5><p>5.Pre Steps<br></p><p>这里的话构建步骤,可以选择自写一些脚本达到不通的构建目的。此处我有使用到,是为了配合构建回滚使用。</p><p>构建回滚这个问题也让我困扰许久看了很多博客都没有成功,其中一篇博客算对我帮助比较大的下面贴一下。</p><p><a href="https://www.jianshu.com/p/dceaa1c7bb49" target="_blank" rel="noopener">使用Jenkins进行项目的自动构建部署</a></p><p>其中的构建脚本还是有点问题的,后来我问了朋友之后对脚本修改了一下才可用。</p><p>我的构建回滚的shell脚本,此处脚本是配合签名Webhook中对参数进行构建的关键:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">case $deploy_env in</span><br><span class="line"> deploy)</span><br><span class="line"> echo "deploy:$deploy_env"</span><br><span class="line"> mvn clean test package</span><br><span class="line"> ;;</span><br><span class="line"> rollback)</span><br><span class="line"> echo "rollback:$deploy_env"</span><br><span class="line"> echo "version:$version"</span><br><span class="line"> cd ${WORKSPACE}</span><br><span class="line"> rm -r target</span><br><span class="line"> cp -r ${JENKINS_HOME}/jobs/your task name/builds/${version}/archive/target ${WORKSPACE}</span><br><span class="line"> pwd && ls</span><br><span class="line"> ;;</span><br><span class="line"> *)</span><br><span class="line"> exit</span><br><span class="line"> ;;</span><br><span class="line">esac</span><br></pre></td></tr></table></figure><p>6.构建设置</p><p>E-mail Notification 勾选可用在构建成功后给你的E-mail发邮件进行通知。这个需要提前在Jenkins系统配置中配置好你的Jenkins邮箱SMTP以及管理员邮箱,注意SMTP配置的邮箱需与管理员邮箱一致。这里也是我踩过的坑,略提一句。</p><p>7.构建完成后的操作</p><h4 id="这里是我们的最后一步了"><a href="#这里是我们的最后一步了" class="headerlink" title="这里是我们的最后一步了"></a>这里是我们的最后一步了</h4><ul><li><p>第一个红框是对构建完成后的项目存档操作以便于后期用于构建回滚操作,非必须。</p></li><li><p>第二红框为远程部署到Tomcat容器的打包文件类型</p></li><li><p>第三红框为远程部署到Tomcat容器的打包文件名</p></li><li><p>第四红框为远程部署到Tomcat容器的账号配置以及远程Tomcat容器的URl管理地址</p></li></ul><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_task_last.png" alt="last"></p><p>8.构建或回滚</p><h4 id="这里演示的是手动进行构建或回滚操作"><a href="#这里演示的是手动进行构建或回滚操作" class="headerlink" title="这里演示的是手动进行构建或回滚操作"></a>这里演示的是手动进行构建或回滚操作</h4><p><img src="/2018/08/04/Docker-Jenkins-Gogs持续集成自动化部署/jenkins_task_builder.png" alt="builder"></p><h2 id="额,基本到这里就结束了吧好久没写博客真的很累 ̄□ ̄||,关于Nenux3的使用下次再写。"><a href="#额,基本到这里就结束了吧好久没写博客真的很累 ̄□ ̄||,关于Nenux3的使用下次再写。" class="headerlink" title="额,基本到这里就结束了吧好久没写博客真的很累 ̄□ ̄||,关于Nenux3的使用下次再写。"></a>额,基本到这里就结束了吧好久没写博客真的很累 ̄□ ̄||,关于Nenux3的使用下次再写。</h2>]]></content>
<tags>
<tag> 随记 </tag>
</tags>
</entry>
</search>