This commit is contained in:
Redkale
2017-06-01 14:00:51 +08:00
parent cef85c40fe
commit 9cf46443a0
4 changed files with 228 additions and 13 deletions

215
course02_rest.html Normal file
View File

@@ -0,0 +1,215 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Redkale(红菜苔)--基于Java 8全新的微服务开源框架 - Redkale官网</title>
<meta name="keywords" content="Redkale,redkale,java,微服务,架构"/>
<meta name="description" content="Redkale(红菜苔)是基于Java 8全新的微服务开源框架"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
</head>
<body>
<section class="page-header">
<a href="index.html" class="project-name">Redkale</a>
<h2 class="project-tagline"></h2>
<a href="redkale.html" class="btn">Redkale 入门</a>
<a href="convert.html" class="btn">Convert 组件</a>
<a href="service.html" class="btn">Service 组件</a>
<a href="source.html" class="btn">Source 组件</a>
<a href="net.html" class="btn">Net 组件</a>
<a href="watch.html" class="btn">Watch 组件</a>
<a href="plugins.html" class="btn">Redkale 插件</a>
<a href="articles.html" class="btn">技术文章</a>
</section>
<section class="main-content">
<h3>Redkale 入门教程 02 -- REST敏捷开发</h3>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REST是 <a href="index.html" target="_blank">Redkale</a> 的主要功能之一REST提供的功能是根据Service自动生成HttpServlet需要注意的是 <b>Redkale里的REST与标准的RESTfull规范完全不同仅仅名称类似</b>。标准的REST规范比较死板只是在请求URL和Method上做文章功能单一。Redkale里的REST功能是很强大的 无论登陆、鉴权、文件上传下载、WebSocket都可以REST化几乎完全可以省去HttpServlet。<br/>
</p>
<table style="margin: auto;">
<tr><th>注解类名</th><th>功能描述</th></tr>
<tr><td style="text-align: left;">@RestService</td><td>标记Service需要REST化。</td></tr>
<tr><td style="text-align: left;">@RestMapping</td><td>标记请求的方法名,同一方法上可重复标记(需确保name值在Service中是唯一的)。<br><b>其标记的Service方法只能throws IOException或不抛异常</b></td></tr>
<tr><td style="text-align: left;">@RestParam</td><td>获取常规参数值, 字段类型可以是 基础数据类型/Flipper/AsyncHandler/String/JavaBean<br>name='&#38;'&nbsp;&nbsp;&nbsp;&nbsp;表示当前用户(@HttpUserType)<br>name='#'&nbsp;&nbsp;&nbsp;&nbsp;表示截取uri最后一段<br>name='#xxx:'&nbsp;&nbsp;&nbsp;&nbsp;表示从uri中/pipes/xxx:v/截取xxx:的值</td></tr>
<tr><td style="text-align: left;">@RestHeader</td><td>通过request.getHeader获取参数值, 字段类型只能是String</td></tr>
<tr><td style="text-align: left;">@RestCookie</td><td>通过request.getCookie获取Cookie值, 字段类型只能是String</td></tr>
<tr><td style="text-align: left;">@RestBody<td>通过request.getBody获取参数值, 字段类型只能是String/byte[]/JavaBean</td></tr>
<tr><td style="text-align: left;">@RestSessionid<td>获取sessionid, 字段类型只能是String</td></tr>
<tr><td style="text-align: left;">@RestAddress<td>获取客户端IP地址, 字段类型只能是String</td></tr>
<tr><td style="text-align: left;">@RestURI</td><td>获取请求URL, 字段类型只能是String</td></tr>
<tr><td style="text-align: left;">@RestUploadFile</td><td>获取上传文件, 字段类型只能是File/File[]/byte[]</td></tr>
<tr><td style="text-align: center;font-size: 0.9rem;" colspan="2"><b>WebSocket</b></td></tr>
<tr><td style="text-align: left;">@RestWebSocket</td><td>标记WebSocket需要REST化只能标记在WebSocket的子类上</td></tr>
<tr><td style="text-align: left;">@RestOnMessage</td><td>WebSocket的消息路由类似@RestMapping不同的请求映射到不同的方法</td></tr>
</table>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;标记@RestService的Service对象在服务启动时会自动生成原始的HttpServlet加载到当前的HttpServer中其HttpServlet的请求URL规则为path + "/" + @RestService.catalog() + "/" + @RestService.name() + "/*" 其中path为application.xml文件中&#60;rest&#62;节点的path属性值。节点rest和servlets设计一个path属性是为了所有动态请求加个前缀方便静动分离没有采取.jsp .do那种刷存在感的后缀方式也是处于安全考虑外界根据URL无法判断后台使用的是什么语言或框架开发。<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REST会根据Service方法的返回类型不同做出不同的结果输出。
<table style="margin: auto;">
<tr><th>返回类型</th><th>功能描述</th></tr>
<tr><td style="text-align: left;">void</td><td>以RetResult.success()的JSON形式输出。</td></tr>
<tr><td style="text-align: left;">String</td><td>以字符串输出。</td></tr>
<tr><td style="text-align: left;">File</td><td>以下载文件形式输出。</td></tr>
<tr><td style="text-align: left;">HttpResult</td><td>将HttpHeader、HttpCookie、Result统一输出</td></tr>
<tr><td style="text-align: left;">CompletableFuture<td>异步输出根据CompletableFuture.get()结果类型进行不同形式输出</td></tr>
<tr><td style="text-align: left;">JavaBean/其他<td>以JSON形式输出</td></tr>
</table>
</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;要开启REST功能需要在application.xml对应的HttpServer下加入rest节点:
</p>
<p style="text-align: center;"><img src="images/rest_01.png" alt=""/></p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果需要加入鉴权功能更需要自定义HttpServlet基类并重载preExecute、authenticate方法。详情见 <a href="http://redkale.org/net.html#baseservlet">BaseHttpServlet</a>
</p>
<p>用户登陆范例</p>
<div class="highlight"><pre><span></span><span class="nd">@RestService</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"user"</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"用户服务"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserService</span> <span class="kd">extends</span> <span class="n">AbstractService</span> <span class="o">{</span>
<span class="nd">@RestMapping</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"login"</span><span class="o">,</span> <span class="n">auth</span> <span class="o">=</span> <span class="kc">false</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"用户登陆"</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">RetResult</span> <span class="nf">login</span><span class="o">(</span><span class="n">String</span> <span class="n">account</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="nd">@RestHeader</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"User-Agent"</span><span class="o">)</span> <span class="n">String</span> <span class="n">agent</span><span class="o">,</span>
<span class="nd">@RestSessionid</span><span class="o">(</span><span class="n">create</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span> <span class="n">String</span> <span class="n">sessionid</span><span class="o">,</span> <span class="nd">@RestAddress</span> <span class="n">String</span> <span class="n">clientAddr</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(!</span><span class="s">"redkale"</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">account</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1001</span><span class="o">,</span> <span class="s">"账号不是redkale"</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">if</span> <span class="o">(!</span><span class="s">"123456"</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">password</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1002</span><span class="o">,</span> <span class="s">"密码错误"</span><span class="o">);</span>
<span class="o">}</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"用户("</span> <span class="o">+</span> <span class="n">account</span> <span class="o">+</span> <span class="s">")的回话ID为: "</span> <span class="o">+</span> <span class="n">sessionid</span> <span class="o">+</span> <span class="s">", 通过客户端("</span> <span class="o">+</span> <span class="n">agent</span> <span class="o">+</span> <span class="s">")在"</span> <span class="o">+</span> <span class="n">clientAddr</span> <span class="o">+</span> <span class="s">"登陆。"</span><span class="o">);</span>
<span class="k">return</span> <span class="n">RetResult</span><span class="o">.</span><span class="na">success</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;浏览器输入: http://127.0.0.1:6060/pipes/user/login?account=redkale&password=123456 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回结果: {"retcode":0,"success":true} <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后台打印: 用户(redkale)的回话ID为: 6110627db03b2b4a2c45a2fcb2aa1403, 通过客户端(Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36)在127.0.0.1登陆。
</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REST的注解不仅可以注解在Service的方法参数上 还可以在Service的方法的JavaBean参数的类里的字段进行注解。
</p>
<div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">class</span> <span class="nc">LoginBean</span> <span class="o">{</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">account</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">password</span><span class="o">;</span>
<span class="nd">@RestHeader</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"User-Agent"</span><span class="o">)</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">agent</span><span class="o">;</span>
<span class="nd">@RestSessionid</span><span class="o">(</span><span class="n">create</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">sessionid</span><span class="o">;</span>
<span class="nd">@RestAddress</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">clientAddr</span><span class="o">;</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">JsonConvert</span><span class="o">.</span><span class="na">root</span><span class="o">().</span><span class="na">convertTo</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">}</span>
<span class="cm">/** 以下省略getter setter方法 */</span>
<span class="o">}</span>
<span class="nd">@RestService</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"user"</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"用户服务"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserService</span> <span class="kd">extends</span> <span class="n">AbstractService</span> <span class="o">{</span>
<span class="nd">@RestMapping</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"login"</span><span class="o">,</span> <span class="n">auth</span> <span class="o">=</span> <span class="kc">false</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"用户登陆"</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">RetResult</span> <span class="nf">login</span><span class="o">(</span><span class="n">LoginBean</span> <span class="n">bean</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">bean</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1000</span><span class="o">,</span> <span class="s">"没有登陆信息"</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">if</span> <span class="o">(!</span><span class="s">"redkale"</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">bean</span><span class="o">.</span><span class="na">getAccount</span><span class="o">()))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1001</span><span class="o">,</span> <span class="s">"账号不是redkale"</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">if</span> <span class="o">(!</span><span class="s">"123456"</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">bean</span><span class="o">.</span><span class="na">getPassword</span><span class="o">()))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1002</span><span class="o">,</span> <span class="s">"密码错误"</span><span class="o">);</span>
<span class="o">}</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"用户("</span> <span class="o">+</span> <span class="n">bean</span><span class="o">.</span><span class="na">getAccount</span><span class="o">()</span> <span class="o">+</span> <span class="s">")通过客户端("</span> <span class="o">+</span> <span class="n">bean</span><span class="o">.</span><span class="na">getAgent</span><span class="o">()</span> <span class="o">+</span> <span class="s">")在"</span> <span class="o">+</span> <span class="n">bean</span><span class="o">.</span><span class="na">getClientAddr</span><span class="o">()</span> <span class="o">+</span> <span class="s">"登陆。"</span><span class="o">);</span>
<span class="k">return</span> <span class="n">RetResult</span><span class="o">.</span><span class="na">success</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;浏览器输入: http://127.0.0.1:6160/pipes/user/login?bean={account:redkale,password:123456} <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回结果: {"retcode":0,"success":true} <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后台打印: 用户(redkale)通过客户端(Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36)在127.0.0.1登陆。
</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果用户登陆成功后需要跳转到首页或者还可能需要输出一些Cookie值就需要使用HttpResult作为返回结果例如
</p>
<div class="highlight"><pre><span></span><span class="nd">@RestService</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"user"</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"用户服务"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserService</span> <span class="kd">extends</span> <span class="n">AbstractService</span> <span class="o">{</span>
<span class="nd">@RestMapping</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"login"</span><span class="o">,</span> <span class="n">auth</span> <span class="o">=</span> <span class="kc">false</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"用户登陆"</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">HttpResult</span> <span class="nf">login</span><span class="o">(</span><span class="n">LoginBean</span> <span class="n">bean</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">bean</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">HttpResult</span><span class="o">&lt;&gt;(</span><span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1000</span><span class="o">,</span> <span class="s">"没有登陆信息"</span><span class="o">));</span>
<span class="o">}</span>
<span class="k">if</span> <span class="o">(!</span><span class="s">"redkale"</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">bean</span><span class="o">.</span><span class="na">getAccount</span><span class="o">()))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">HttpResult</span><span class="o">&lt;&gt;(</span><span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1001</span><span class="o">,</span> <span class="s">"账号不是redkale"</span><span class="o">));</span>
<span class="o">}</span>
<span class="k">if</span> <span class="o">(!</span><span class="s">"123456"</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">bean</span><span class="o">.</span><span class="na">getPassword</span><span class="o">()))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">HttpResult</span><span class="o">&lt;&gt;(</span><span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1002</span><span class="o">,</span> <span class="s">"密码错误"</span><span class="o">));</span>
<span class="o">}</span>
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"用户("</span> <span class="o">+</span> <span class="n">bean</span><span class="o">.</span><span class="na">getAccount</span><span class="o">()</span> <span class="o">+</span> <span class="s">")通过客户端("</span> <span class="o">+</span> <span class="n">bean</span><span class="o">.</span><span class="na">getAgent</span><span class="o">()</span> <span class="o">+</span> <span class="s">")在"</span> <span class="o">+</span> <span class="n">bean</span><span class="o">.</span><span class="na">getClientAddr</span><span class="o">()</span> <span class="o">+</span> <span class="s">"登陆。"</span><span class="o">);</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">HttpResult</span><span class="o">().</span><span class="na">header</span><span class="o">(</span><span class="s">"Location"</span><span class="o">,</span> <span class="s">"/index.html"</span><span class="o">).</span><span class="na">cookie</span><span class="o">(</span><span class="k">new</span> <span class="n">HttpCookie</span><span class="o">(</span><span class="s">"curraccount"</span><span class="o">,</span> <span class="n">bean</span><span class="o">.</span><span class="na">getAccount</span><span class="o">()));</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
<p>文件上传</p>
<div class="highlight"><pre><span></span><span class="nd">@RestService</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"file"</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"文件服务"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">FileService</span> <span class="kd">extends</span> <span class="n">AbstractService</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">format</span> <span class="o">=</span> <span class="s">"%1$tY%1$tm%1$td%1$tH%1$tM%1$tS"</span><span class="o">;</span>
<span class="nd">@RestMapping</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"upload"</span><span class="o">,</span> <span class="n">auth</span> <span class="o">=</span> <span class="kc">false</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"文件上传,不鉴权"</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">RetResult</span> <span class="nf">upload</span><span class="o">(</span><span class="nd">@RestUploadFile</span><span class="o">(</span><span class="n">maxLength</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">*</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">1024</span><span class="o">,</span> <span class="n">fileNameReg</span> <span class="o">=</span> <span class="s">".*\\.doc$"</span><span class="o">)</span> <span class="n">File</span> <span class="n">tmpFile</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">IOException</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">tmpFile</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">RetResult</span><span class="o">(</span><span class="mi">1001</span><span class="o">,</span> <span class="s">"没有上传文件或文件大小超过1M或文件不是.doc后缀"</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">//按日期命名 如 file-20170601133520.doc</span>
<span class="k">try</span> <span class="o">{</span>
<span class="n">File</span> <span class="n">destFile</span> <span class="o">=</span> <span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="s">"D:/docs/file-"</span> <span class="o">+</span> <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="n">format</span><span class="o">,</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">())</span> <span class="o">+</span> <span class="s">".doc"</span><span class="o">);</span>
<span class="n">destFile</span><span class="o">.</span><span class="na">getParentFile</span><span class="o">().</span><span class="na">mkdirs</span><span class="o">();</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">tmpFile</span><span class="o">.</span><span class="na">renameTo</span><span class="o">(</span><span class="n">destFile</span><span class="o">))</span> <span class="o">{</span> <span class="c1">//tmpFile与destFile不在同一盘符下会导致renameTo失败</span>
<span class="n">java</span><span class="o">.</span><span class="na">nio</span><span class="o">.</span><span class="na">file</span><span class="o">.</span><span class="na">Files</span><span class="o">.</span><span class="na">copy</span><span class="o">(</span><span class="n">tmpFile</span><span class="o">.</span><span class="na">toPath</span><span class="o">(),</span> <span class="n">destFile</span><span class="o">.</span><span class="na">toPath</span><span class="o">(),</span> <span class="n">StandardCopyOption</span><span class="o">.</span><span class="na">ATOMIC_MOVE</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span> <span class="k">finally</span> <span class="o">{</span> <span class="c1">//如果发生异常,将临时文件从{APP_HOME}/tmp 目录下删除</span>
<span class="n">tmpFile</span><span class="o">.</span><span class="na">delete</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">RetResult</span><span class="o">.</span><span class="na">success</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WebSocket与其REST化将在后面的章节详细介绍。
</p>
<br/>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;转载请注明出处:<a href="https://redkale.org/course02_rest.html" target="_blank">https://redkale.org/course02_rest.html</a>
</p>
<footer class="site-footer">
<span class="site-footer-owner">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;欢迎加入Redkale QQ群: 527523235</span>
</footer>
</section>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "//hm.baidu.com/hm.js?b4e05d7de8b5f3401dd93e3c6b35ffa5";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</body>
</html>