(5);
326 | // Use a StringTokenizer to tokenize the property name.
327 | StringTokenizer tokenizer = new StringTokenizer(name, ".");
328 | while (tokenizer.hasMoreTokens()) {
329 | propName.add(tokenizer.nextToken());
330 | }
331 | return propName.toArray(new String[propName.size()]);
332 | }
333 |
334 | private Element getElement(String name) {
335 | String[] propName = parsePropertyName(name);
336 | // Search for this property by traversing down the XML heirarchy.
337 | Element element = document.getRootElement();
338 | for (int i = 0; i < propName.length; i++) {
339 | element = element.element(propName[i]);
340 | // Can't find the property so return.
341 | if (element == null) {
342 | break;
343 | }
344 | }
345 | return element;
346 | }
347 |
348 | /**
349 | * Saves the properties to disk as an XML document. A temporary file is
350 | * used during the writing process for maximum safety.
351 | */
352 | private synchronized void saveProperties() {
353 | boolean error = false;
354 | // Write data out to a temporary file first.
355 | File tempFile = null;
356 | Writer writer = null;
357 | try {
358 | tempFile = new File(file.getParentFile(), file.getName() + ".tmp");
359 | writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile), "UTF-8"));
360 | OutputFormat prettyPrinter = OutputFormat.createPrettyPrint();
361 | XMLWriter xmlWriter = new XMLWriter(writer, prettyPrinter);
362 | xmlWriter.write(document);
363 | }
364 | catch (Exception e) {
365 | Log.error(e.getMessage(), e);
366 | // There were errors so abort replacing the old property file.
367 | error = true;
368 | }
369 | finally {
370 | if (writer != null) {
371 | try {
372 | writer.close();
373 | }
374 | catch (IOException e1) {
375 | Log.error(e1.getMessage(), e1);
376 | error = true;
377 | }
378 | }
379 | }
380 |
381 | // No errors occured, so delete the main file.
382 | if (!error) {
383 | // Delete the old file so we can replace it.
384 | if (!file.delete()) {
385 | Log.error("Error deleting property file: " + file.getAbsolutePath());
386 | return;
387 | }
388 | // Copy new contents to the file.
389 | try {
390 | copy(tempFile, file);
391 | }
392 | catch (Exception e) {
393 | Log.error(e.getMessage(), e);
394 | // There were errors so abort replacing the old property file.
395 | error = true;
396 | }
397 | // If no errors, delete the temp file.
398 | if (!error) {
399 | tempFile.delete();
400 | }
401 | }
402 | }
403 |
404 | /**
405 | * Copies the inFile to the outFile.
406 | *
407 | * @param inFile The file to copy from
408 | * @param outFile The file to copy to
409 | * @throws java.io.IOException If there was a problem making the copy
410 | */
411 | private static void copy(File inFile, File outFile) throws IOException {
412 | FileInputStream fin = null;
413 | FileOutputStream fout = null;
414 | try {
415 | fin = new FileInputStream(inFile);
416 | fout = new FileOutputStream(outFile);
417 | copy(fin, fout);
418 | }
419 | finally {
420 | try {
421 | if (fin != null) fin.close();
422 | }
423 | catch (IOException e) {
424 | // do nothing
425 | }
426 | try {
427 | if (fout != null) fout.close();
428 | }
429 | catch (IOException e) {
430 | // do nothing
431 | }
432 | }
433 | }
434 |
435 | /**
436 | * Copies data from an input stream to an output stream
437 | *
438 | * @param in the stream to copy data from.
439 | * @param out the stream to copy data to.
440 | * @throws java.io.IOException if there's trouble during the copy.
441 | */
442 | private static void copy(InputStream in, OutputStream out) throws IOException {
443 | // Do not allow other threads to intrude on streams during copy.
444 | synchronized (in) {
445 | synchronized (out) {
446 | byte[] buffer = new byte[256];
447 | while (true) {
448 | int bytesRead = in.read(buffer);
449 | if (bytesRead == -1) break;
450 | out.write(buffer, 0, bytesRead);
451 | }
452 | }
453 | }
454 | }
455 |
456 | public void destroy() {
457 | document = null;
458 | file = null;
459 | propertyCache.clear();
460 | propertyCache = null;
461 |
462 | }
463 | }
464 |
--------------------------------------------------------------------------------
/src/main/webapp/doc/file.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | file.html
6 |
7 |
8 |
9 |
10 |
11 |
12 | 文件上传
接口说明
文件上传是一个通用的总接口,凡是涉及文件上传操作的功能,请先调用文件上传接口,返回正确文件访问路径后,再提交纯文本表单。即提交文本表单时,用户头像、图片相关的表单字段,为上传接口返回的URL值。
url
/api/fs/upload
14 |
method
post
16 |
参数
17 | - token:必要参数,为空或错误将不能上传。token可以从登录后的用户信息里获得(不登录是无法获取上传权限的)
该接口支持单文件及多文件上传, 每个文件对应一个请求参数, 如: file1对应a.jpg, file2对应b.jpg
响应结果说明
节点说明:
18 | - code:表示响应结果状态,1表示成功,0表示有一或多个文件上传失败
- message:响应结果的文字说明
- failed: 此字段标记上传失败的请求参数名称(名称对应上传时所传递的文件),如: [‘file1’,’file2’]
- datum: 此字段返回了上传成功的文件所对应的文件地址, key为上传时传递的请求参数, value为文件地址
上传成功
{
26 | code: 1,
27 | datum: {
28 | fileUpload1: "/imgs/2015/02/01/20131117223307_JMMX5.thumb.700_0.jpeg",
29 | fileUpload2: "/imgs/2015/02/01/shortcut.png"
30 | }
31 | }
32 |
包含上传失败的文件
{
37 | code: 0,
38 | failed: ['fileUpload1']
39 | }
40 |
请求中未包含文件
{
45 | message: "uploadFileName can not be null",
46 | code: 2
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/src/main/webapp/doc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | index.html
6 |
7 |
8 |
9 |
10 |
11 |
12 | HTTP API文档 总览
意见反馈
URL
/api/feedback
14 |
METHOD
POST(必须是POST)
16 |
参数
17 | - token:令牌(可选项)
- suggestion: 内容(必需项)
响应结果说明
节点说明:
18 | - code:表示响应结果状态,1表示成功,0表示失败
- message:响应结果的文字说明
简要示例
{
23 | "code": 1,
24 | "message": "意见反馈成功"
25 | }
26 |
版本更新检查
URL
/api/version/check
28 |
METHOD
GET
30 |
参数
31 | - version:当前客户端版本号(必需项)
- client: 客户端类型, 可选值只能是android和iphone(必需项)
响应结果说明
节点说明:
32 | - code:表示响应结果状态,1表示有更新,0表示无更新
- message:响应结果状态的文字说明
datum节点说明:
33 | - message: 更新说明
- url: 新版本下载地址
- version: 新版本号
简要示例
{
42 | "code": 1,
43 | "datum": {
44 | "message": "修复bug",
45 | "url": "http://mlongbo.com/android_0_1_1.apk",
46 | "version": "0.1.2"
47 | }
48 | }
49 |
附录(很重要)
文件地址说明
接口中所有的文件地址都是相对路径, 需要拼接地址前缀才能正常使用.
在登录成功后,登录接口返回的resourceServer字段为地址前缀.
如: resourceServer为http://mlongbo.com, 用户头像地址为/img/avatar/rose.jpg,
那么完整的地址就是http://mlongbo.com/img/avatar/rose.jpg
时间戳说明
文档中提到的时间戳全部精确到毫秒
code对照表
50 | - 1 ok - 成功状态
- 0 faild
- 2 argument error - 表示请求参数值有误, 或未携带需要的参数值
- 3 帐号已存在
- 4 验证码错误
- 500 error - 服务器错误
- 404 not found - 请求的资源或接口不存在
- 422 token error - 未传递token参数,或token值非法
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------