Files
redkale/course02_rest.html
Redkale 45896a5f62
2017-10-20 09:57:30 +08:00

218 lines
28 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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;">@RestConvert</td><td>标记请求的方法名上对返回值以JSON形式输出时进行字段的屏蔽或开启进行设置</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="n">tmpFile</span><span class="o">.</span><span class="na">getParentFile</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>