Java:Spring MVC上传文件实战

一直很麻烦

说实话,Java的上传文件,还是稍微有点麻烦,要自己集成很多东西.在这一点上,我发现我更喜欢Flask的文件上传,寥寥几行就可以搞定文件上传.

看个Flask官方的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect(url_for('uploaded_file',
                                    filename=filename))
    return '''
    <!doctype html>
    <title>Upload new File</title>
    <h1>Upload new File</h1>
    <form action="" method=post enctype=multipart/form-data>
      <p><input type=file name=file>
         <input type=submit value=Upload>
    </form>
    '''

搞定,关于Flask还有很多美好的传说..有意,请自行探索.

从一而终,看Java文件上传

在这里,我使用了Ajax上传文件.(不刷新页面,可以让你有更大的想象空间)

特诊如下:

  1. 使用了jquery.js,jquery.form.js,layer.js;
  2. 使用Ajax进行文件上传;
  3. 推荐使用iframe的方式进行调用,上传成功之后,ID会放进一个隐藏域.

大概特征如上,下面……兴奋的看源码吧.

java
image-2464

源码有点多…

第一个文件:前台upload.jsp

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
    <title>文件上传</title>
    <meta name="decorator" content="default"/>
    <script type="text/javascript" src="/jquery/jquery.js"></script>
    <script type="text/javascript" src="/jquery/jquery.form.js"></script>
    <script type="text/javascript" src="/layer/layer.js"></script>
    <script type="text/javascript">
    <c:if test="${empty list }">
        $(document).ready(function() {
            $(".deletefile").live("click",function(){ // 动态绑定删除按钮.
                var delid = $(this).data("id");
                var buttondel = $(this);
                if(delid){
                    //询问框
                top.layer.confirm('确认要删除吗?', {
                      btn: ['确认','取消'] //按钮
                    }, function(index){
                        top.layer.close(index);
                        $.ajax({
                            url:"/deleteFile",
                            data:{
                                "fileId":delid
                            },
                            type:"POST",
                            dataType:"json",
                            success:function(data){
                                if(data.status && data.status=='0'){
                                    //将已删除的id从隐藏域中删除
                                    var idStr = $("#resultIdInfo").val();
                                    idStr = idStr.substring(0,idStr.length-1);
                                    var array = idStr.split(",");
                                    var indexarray = array.indexOf(delid);//找到相应ID的项
                                    if (indexarray > -1) {
                                        array.splice(indexarray, 1);//在数组中删除相应项
                                    }
                                    $("#resultIdInfo").val("");
                                    if(array.length>0){//如果没有值了,不要添加.                                       
                                        $("#resultIdInfo").val(array.join(",")+",");
                                    }
                                    buttondel.parent().parent().remove();//删除当前行.
                                }
                            }
                        });
                       
                    });
                }
               
            })
           
           
            $("#upload").click(function(){ // 上传操作
                 var fileinput=$("#file");
                  if($.trim(fileinput.val())==''){ // 判断是否已经选择了文件
                         top.layer.msg('请先选择文件!');
                         return false;
                   }
                      $("#uploadForm").ajaxSubmit({ // 使用ajax上传
                          type: "post",
                          url: $("#uploadForm").attr("action"),
                          success: function (data) {
                                if(data.status && data.status=='0'){//成功.
                                    var objinfo = data.result; // 会返回id和displayName.
                                    if(!checkIdRepeat(objinfo.id)){ // 判断id还不存在
                                        var resultValue = $("#resultIdInfo");
                                        resultValue.val(resultValue.val()+objinfo.id+","); // 添加到隐藏域
                                        $("#fileInfoTable").append(generatorTrHTML(objinfo.id,objinfo.displayName)); // 添加到表格
                                    }
                                    // 清空文件选择
                                    fileinput.after(fileinput.clone().val(""));    
                                    fileinput.remove();    
                                }else{
                                    top.layer.msg(data.msg);
                                }                              
                          },
                          error: function (msg) {
                              top.layer.msg("文件上传失败!");    
                          }
                      });
                      return false;
                 
            })
        });
       
        //拼接html.
        function generatorTrHTML(id,name){
            return "<tr id='"+id+"'><td>"+name+"</td><td><input type='button' data-id='"
                        +id+"' class='btn btn-danger deletefile' value='删除'/>  <input type='button' onclick='window.open("/viewfile/"+id+"")'  class='btn btn-primary' value='下载'/></td></tr>";
        }
       
        // 检查是否已经存在ID了.
        function checkIdRepeat(fileid){
            var resultValue = $("#resultIdInfo").val();
            if(resultValue && resultValue.indexOf(fileid)>0){
                return true;
            }
            return false;
        }
        </c:if>
    </script>
</head>
<body>
    <form:form id="uploadForm" enctype="multipart/form-data" modelAttribute="document" action="/saveFile" method="post" class="breadcrumb form-search ">
        <c:if test="${empty list }"><!-- 如果为空才可以进行文件选择 -->
            <input id="fileUploadType" name="fileUploadType" type="hidden" value="${fileUploadType}"/>
            <input type="file" id="file" name="file" />
            <input type="button" id="upload" class="default"  <c:if test="${empty fileUploadType}">disabled="disabled"</c:if> value="上传"/><c:if test="${empty fileUploadType}"><span>文件上传类型为空,暂时不能上传!</span></c:if>
            <input type="hidden" id="resultIdInfo"  /><!-- 保存文件的ID -->
        </c:if>
        <table id="fileInfoTable">
            <c:forEach items="${list }" var="doc">
                <tr id='${doc.id }'>
                    <td>${doc.displayName }</td>
                    <td>
                        <input type='button' onclick='window.open("/viewfile/${doc.id }")'  class='btn btn-primary' value='下载'/>
                    </td>
                </tr>
            </c:forEach>
       
        </table>
    </form:form>
</body>
</html>

第二个文件:后台Controller.java

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.thinkgem.jeesite.modules.sys.web;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


import com.thinkgem.jeesite.common.utils.FileUploadUtil;
import com.thinkgem.jeesite.common.utils.StringUtils;

/**
 *
 * 文件上传.
 *
 * @author prd
 *
 */
@Controller
@RequestMapping(value = "/")
public class DocumentController {

    @Autowired
    private DocumentService documentService;

    @RequestMapping(value = "uploadFile")
    public String uploadFile(String fileUploadType, String[] fileIds, HttpServletRequest request,
            HttpServletResponse response, Model model) {
        if (null != fileIds && fileIds.length > 0) {
            Document document = new Document();
            document.setIdQuery(Arrays.asList(fileIds));
            List<Document> documentList = documentService.findList(document);
            model.addAttribute("list", documentList);
        }
        model.addAttribute("fileUploadType", fileUploadType);
        return "files";
    }

    /**
     * 下载文件/查看文件.
     *
     * @param model
     * @param response
     * @param filesId
     */
    @RequestMapping(value = "/viewfile/{filesId}", method = RequestMethod.GET)
    public void viewFile(Model model, HttpServletResponse response, @PathVariable("filesId") String filesId) {
        Document result = documentService.get(filesId);
        if (null != result) { // response 显示.
            FileUploadUtil.viewFile(result.getDisplayName(), result.getFilePath(), response);
        }
    }

    /**
     * 删除文件.
     *
     * @param model
     * @param response
     * @param fileId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "deleteFile")
    public AppJson deleteFile(Model model, HttpServletResponse response, String fileId) {
        if (StringUtils.isNotBlank(fileId)) {
            documentService.delete(fileId);
            return new AppJson("0", "文件删除成功!");
        }
        return new AppJson("1", "文件删除错误:文件ID为空!");
    }

    /**
     * 保存文件.
     *
     *
     * @param document
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = { "saveFile" })
    public AppJson saveFile(Document document, HttpServletRequest request, HttpServletResponse response) {
        if (null != document && StringUtils.isNotBlank(document.getFileUploadType())) {
            List<Document> filePathList = new ArrayList<Document>();
            try {
                filePathList = FileUploadUtil.uploadFile(request, response, document.getFileUploadType());
                if (filePathList.size() > 0) {
                    Document newdocument = filePathList.get(0);
                    final String uuid = IdGen.uuid();
                    newdocument.setId(uuid);
                    documentService.save(newdocument);
                    Document result = new Document();
                    result.setId(uuid);
                    result.setDisplayName(newdocument.getDisplayName());
                    return new AppJson("0", "保存成功", result);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return new AppJson("1", e.getMessage());
            } catch (Exception ex) {
                ex.printStackTrace();
                return new AppJson("1", ex.getMessage());
            }
            if (filePathList.size() == 0) {
                return new AppJson("1", "系统错误!");
            }
        }
        return new AppJson("1", "文件上传类型[fileuploadtype]不能为空!");
    }

}

第三个文件:后台-文件实体Document.java

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
92
93
94
95
import java.util.List;


/**
 * 保存文件.
 *
 *
 * @author prd.
 *
 */
public class Document{

    private String id;//数据ID.
    private String fileName; // 文件名.
    private String displayName; // 显示的文件名.
    private String filePath; // 文件保存路径
    private String fileUploadType; // 上传文件的属性:1->用户.
   
   
    private static final String UPLOADTYPE_USER = "1";//用户.
   
    /**
     * 通过数字来获取上传文件的文件名.
     *
     * @param fileUploadTypeInfo
     * @return
     */
    public static String getTypeName(String fileUploadTypeInfo){
        switch(fileUploadTypeInfo){
        case UPLOADTYPE_USER:
            return "user";
        }      
        return "user";
    }
   
   
    public Document(String fileName, String displayName, String filePath, String fileUploadType) {
        this.fileName = fileName;
        this.displayName = displayName;
        this.filePath = filePath;
        this.fileUploadType = fileUploadType;
    }
   
   
    public Document() {
       
    }

    public String getFileName() {
        return fileName;
    }



    public void setFileName(String fileName) {
        this.fileName = fileName;
    }



    public String getDisplayName() {
        return displayName;
    }



    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }



    public String getFilePath() {
        return filePath;
    }



    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }



    public String getFileUploadType() {
        return fileUploadType;
    }



    public void setFileUploadType(String fileUploadType) {
        this.fileUploadType = fileUploadType;
    }

}

第四个文件:后台-字符串工具类

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
/**
 * Copyright © 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.common.utils;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringEscapeUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.LocaleResolver;

import com.google.common.collect.Lists;

/**
 * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
 * @author ThinkGem
 * @version 2013-05-22
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {
   
    private static final char SEPARATOR = '_';
    private static final String CHARSET_NAME = "UTF-8";
   
    /**
     * 转换为字节数组
     * @param str
     * @return
     */
    public static byte[] getBytes(String str){
        if (str != null){
            try {
                return str.getBytes(CHARSET_NAME);
            } catch (UnsupportedEncodingException e) {
                return null;
            }
        }else{
            return null;
        }
    }
   
    /**
     * 转换为字节数组
     * @param str
     * @return
     */
    public static String toString(byte[] bytes){
        try {
            return new String(bytes, CHARSET_NAME);
        } catch (UnsupportedEncodingException e) {
            return EMPTY;
        }
    }
   
    /**
     * 是否包含字符串
     * @param str 验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inString(String str, String... strs){
        if (str != null){
            for (String s : strs){
                if (str.equals(trim(s))){
                    return true;
                }
            }
        }
        return false;
    }
   
    /**
     * 替换掉HTML标签方法
     */
    public static String replaceHtml(String html) {
        if (isBlank(html)){
            return "";
        }
        String regEx = "<.+?>";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(html);
        String s = m.replaceAll("");
        return s;
    }
   
    /**
     * 替换为手机识别的HTML,去掉样式及属性,保留回车。
     * @param html
     * @return
     */
    public static String replaceMobileHtml(String html){
        if (html == null){
            return "";
        }
        return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
    }
   
    /**
     * 替换为手机识别的HTML,去掉样式及属性,保留回车。
     * @param txt
     * @return
     */
    public static String toHtml(String txt){
        if (txt == null){
            return "";
        }
        return replace(replace(Encodes.escapeHtml(txt), "\n", "<br/>"), "\t", "    ");
    }

    /**
     * 缩略字符串(不区分中英文字符)
     * @param str 目标字符串
     * @param length 截取长度
     * @return
     */
    public static String abbr(String str, int length) {
        if (str == null) {
            return "";
        }
        try {
            StringBuilder sb = new StringBuilder();
            int currentLength = 0;
            for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
                currentLength += String.valueOf(c).getBytes("GBK").length;
                if (currentLength <= length - 3) {
                    sb.append(c);
                } else {
                    sb.append("...");
                    break;
                }
            }
            return sb.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
   
    public static String abbr2(String param, int length) {
        if (param == null) {
            return "";
        }
        StringBuffer result = new StringBuffer();
        int n = 0;
        char temp;
        boolean isCode = false; // 是不是HTML代码
        boolean isHTML = false; // 是不是HTML特殊字符,如 
        for (int i = 0; i < param.length(); i++) {
            temp = param.charAt(i);
            if (temp == '<') {
                isCode = true;
            } else if (temp == '&') {
                isHTML = true;
            } else if (temp == '>' && isCode) {
                n = n - 1;
                isCode = false;
            } else if (temp == ';' && isHTML) {
                isHTML = false;
            }
            try {
                if (!isCode && !isHTML) {
                    n += String.valueOf(temp).getBytes("GBK").length;
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            if (n <= length - 3) {
                result.append(temp);
            } else {
                result.append("...");
                break;
            }
        }
        // 取出截取字符串中的HTML标记
        String temp_result = result.toString().replaceAll("(>)[^<>]*(<?)",
                "$1$2");
        // 去掉不需要结素标记的HTML标记
        temp_result = temp_result
                .replaceAll(
                        "</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>",
                        "");
        // 去掉成对的HTML标记
        temp_result = temp_result.replaceAll("<([a-zA-Z]+)[^<>]*>(.*?)</\\1>",
                "$2");
        // 用正则表达式取出标记
        Pattern p = Pattern.compile("<([a-zA-Z]+)[^<>]*>");
        Matcher m = p.matcher(temp_result);
        List<String> endHTML = Lists.newArrayList();
        while (m.find()) {
            endHTML.add(m.group(1));
        }
        // 补全不成对的HTML标记
        for (int i = endHTML.size() - 1; i >= 0; i--) {
            result.append("</");
            result.append(endHTML.get(i));
            result.append(">");
        }
        return result.toString();
    }
   
    /**
     * 转换为Double类型
     */
    public static Double toDouble(Object val){
        if (val == null){
            return 0D;
        }
        try {
            return Double.valueOf(trim(val.toString()));
        } catch (Exception e) {
            return 0D;
        }
    }

    /**
     * 转换为Float类型
     */
    public static Float toFloat(Object val){
        return toDouble(val).floatValue();
    }

    /**
     * 转换为Long类型
     */
    public static Long toLong(Object val){
        return toDouble(val).longValue();
    }

    /**
     * 转换为Integer类型
     */
    public static Integer toInteger(Object val){
        return toLong(val).intValue();
    }
   
    /**
     * 获得i18n字符串
     */
    public static String getMessage(String code, Object[] args) {
        LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class);
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();  
        Locale localLocale = localLocaleResolver.resolveLocale(request);
        return SpringContextHolder.getApplicationContext().getMessage(code, args, localLocale);
    }
   
    /**
     * 获得用户远程地址
     */
    public static String getRemoteAddr(HttpServletRequest request){
        String remoteAddr = request.getHeader("X-Real-IP");
        if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("X-Forwarded-For");
        }else if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("Proxy-Client-IP");
        }else if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("WL-Proxy-Client-IP");
        }
        return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
    }

    /**
     * 驼峰命名法工具
     * @return
     *      toCamelCase("hello_world") == "helloWorld"
     *      toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *      toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }

        s = s.toLowerCase();

        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    /**
     * 驼峰命名法工具
     * @return
     *      toCamelCase("hello_world") == "helloWorld"
     *      toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *      toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCapitalizeCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = toCamelCase(s);
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }
   
    /**
     * 驼峰命名法工具
     * @return
     *      toCamelCase("hello_world") == "helloWorld"
     *      toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *      toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toUnderScoreCase(String s) {
        if (s == null) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            boolean nextUpperCase = true;

            if (i < (s.length() - 1)) {
                nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
            }

            if ((i > 0) && Character.isUpperCase(c)) {
                if (!upperCase || !nextUpperCase) {
                    sb.append(SEPARATOR);
                }
                upperCase = true;
            } else {
                upperCase = false;
            }

            sb.append(Character.toLowerCase(c));
        }

        return sb.toString();
    }
   
    /**
     * 如果不为空,则设置值
     * @param target
     * @param source
     */
    public static void setValueIfNotBlank(String target, String source) {
        if (isNotBlank(source)){
            target = source;
        }
    }
 
    /**
     * 转换为JS获取对象值,生成三目运算返回结果
     * @param objectString 对象串
     *   例如:row.user.id
     *   返回:!row?'':!row.user?'':!row.user.id?'':row.user.id
     */
    public static String jsGetVal(String objectString){
        StringBuilder result = new StringBuilder();
        StringBuilder val = new StringBuilder();
        String[] vals = split(objectString, ".");
        for (int i=0; i<vals.length; i++){
            val.append("." + vals[i]);
            result.append("!"+(val.substring(1))+"?'':");
        }
        result.append(val.substring(1));
        return result.toString();
    }
   
}

第五个文件:后台-日期工具类

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/**
 * Copyright © 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.common.utils;

import java.text.ParseException;
import java.util.Date;

import org.apache.commons.lang3.time.DateFormatUtils;

/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 * @author ThinkGem
 * @version 2014-4-15
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
   
    private static String[] parsePatterns = {
        "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
        "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
        "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 得到当前日期字符串 格式(yyyy-MM-dd)
     */
    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }
   
    /**
     * 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }
   
    /**
     * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }
   
    /**
     * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前时间字符串 格式(HH:mm:ss)
     */
    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    /**
     * 得到当前日期和时间字符串 格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前年份字符串 格式(yyyy)
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串 格式(MM)
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到当天字符串 格式(dd)
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到当前星期字符串 格式(E)星期几
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }
   
    /**
     * 日期型字符串转化为日期 格式
     * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
     *   "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm",
     *   "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
     */
    public static Date parseDate(Object str) {
        if (str == null){
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = new Date().getTime()-date.getTime();
        return t/(24*60*60*1000);
    }

    /**
     * 获取过去的小时
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
        long t = new Date().getTime()-date.getTime();
        return t/(60*60*1000);
    }
   
    /**
     * 获取过去的分钟
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
        long t = new Date().getTime()-date.getTime();
        return t/(60*1000);
    }
   
    /**
     * 转换为时间(天,时:分:秒.毫秒)
     * @param timeMillis
     * @return
     */
    public static String formatDateTime(long timeMillis){
        long day = timeMillis/(24*60*60*1000);
        long hour = (timeMillis/(60*60*1000)-day*24);
        long min = ((timeMillis/(60*1000))-day*24*60-hour*60);
        long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60);
        long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000);
        return (day>0?day+",":"")+hour+":"+min+":"+s+"."+sss;
    }
   
    /**
     * 获取两个日期之间的天数
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }
   
    /**
     * @param args
     * @throws ParseException
     */
    public static void main(String[] args) throws ParseException {
//      System.out.println(formatDate(parseDate("2010/3/6")));
//      System.out.println(getDate("yyyy年MM月dd日 E"));
//      long time = new Date().getTime()-parseDate("2012-11-19").getTime();
//      System.out.println(time/(24*60*60*1000));
    }
}

第六个文件:后台-ID生成工具类

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
/**
 * Copyright © 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.common.utils;

import java.io.Serializable;
import java.security.SecureRandom;
import java.util.UUID;

import org.activiti.engine.impl.cfg.IdGenerator;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

/**
 * 封装各种生成唯一性ID算法的工具类.
 * @author ThinkGem
 * @version 2013-01-15
 */
@Service
@Lazy(false)
public class IdGen implements IdGenerator, SessionIdGenerator {

    private static SecureRandom random = new SecureRandom();
   
    /**
     * 封装JDK自带的UUID, 通过Random数字生成, 中间无-分割.
     */
    public static String uuid() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
   
    /**
     * 使用SecureRandom随机生成Long.
     */
    public static long randomLong() {
        return Math.abs(random.nextLong());
    }

    /**
     * 基于Base62编码的SecureRandom随机生成bytes.
     */
    public static String randomBase62(int length) {
        byte[] randomBytes = new byte[length];
        random.nextBytes(randomBytes);
        return Encodes.encodeBase62(randomBytes);
    }
   
    /**
     * Activiti ID 生成
     */
    @Override
    public String getNextId() {
        return IdGen.uuid();
    }

    @Override
    public Serializable generateId(Session session) {
        return IdGen.uuid();
    }
   
    public static void main(String[] args) {
        System.out.println(IdGen.uuid());
        System.out.println(IdGen.uuid().length());
        System.out.println(new IdGen().getNextId());
        for (int i=0; i<1000; i++){
            System.out.println(IdGen.randomLong() + "  " + IdGen.randomBase62(5));
        }
    }

}

第七个文件:后台-上传处理Service

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
import java.io.File;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;



@Service
@Transactional(readOnly = true)
public class DocumentService   {
   
   
    @Transactional(readOnly=false)
    public void save(Document document){
        // codeing...... 保存到数据库
    }
   
   
    public List<Document> findList(Document document){
        // coding...... 从数据库查询数据
        return null ;
    }
   
    @Transactional(readOnly = false)
    public void delete(Document document){
        // coding...... 删除数据
    }
   
    @Transactional(readOnly = false)
    public void delete(String id){
        // coding...... 删除数据
        Document document = null;// TODO 先从数据库获取对象数据
        if(null!=document){
            File file = new File(document.getFilePath()); // 找到文件系统中的文件
            if(file.exists()){ // 文件系统中存在
                file.delete(); // 删除文件系统中的文件.
                //delete(document); // 删除数据库中的数据
            }
        }
    }
   

}

第八个文件:后台-【文件上传处理类】【核心】

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;


/**
 * 上传文件
 * @author scar
 *
 */
public class FileUploadUtil {
   
   
    private static Log log = LogFactory.getLog(FileUploadUtil.class);
    public static List<Document> uploadFile(HttpServletRequest request,
            HttpServletResponse response, String uploadFileType) throws FileNotFoundException{
        List<Document> filePathList = new ArrayList<Document>();
       
        String strPath = ",webapps,files,"+Document.getTypeName(uploadFileType);
       
        String filepath =   strPath.replace(",", "/");
       
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
       
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        String fileName = null;
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {

            MultipartFile mf = entity.getValue();
            fileName = mf.getOriginalFilename();
            String fileType = fileName.substring(fileName.lastIndexOf('.'));
            try {
                String newFileName = MD5FileUtil.getMD5String(mf.getBytes());
                String newfilepath;
                newfilepath = filepath + "/" + newFileName + fileType;

                File dest = new File(filepath);
                if(!dest.exists()){
                    dest.mkdirs();
                }
                File uploadFile = new File(newfilepath);
                if(uploadFile.exists()){
                    uploadFile.delete();
                }
                log.info("start upload file: " + fileName);
                FileCopyUtils.copy(mf.getBytes(), uploadFile);
                Document filesnew = new Document();
                filesnew.setFileUploadType(uploadFileType);
                filesnew.setDisplayName(fileName);
                filesnew.setFileName(newFileName + fileType);
                filesnew.setFilePath(newfilepath);
                filePathList.add(filesnew);

            } catch (IOException e) {
                e.printStackTrace();
                log.info("upload failed. filename: " + fileName + e.getMessage());
                return null;
            }
        }
        return filePathList;
    }
   
    /**
     * 向前台输出文件.
     *
     *
     * @param path
     * @param response
     * @return
     */
    public static HttpServletResponse download(String path, HttpServletResponse response) {
        try {
            // path是指欲下载的文件的路径。
            File file = new File(path);
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            //String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            response.setContentType("multipart/form-data");  
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return response;
    }
   
   
    /**
     * 向前台输出文件.
     *
     *
     * @param path
     * @param response
     * @return
     */
    public static HttpServletResponse viewFile(String fileDisplayName,String path, HttpServletResponse response) {
        try {
            // path是指欲下载的文件的路径。
            File file = new File(path);
           /* // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();*/

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileDisplayName.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            String contentType = java.nio.file.Files.probeContentType(Paths.get(path));
            System.out.println("contentType:"+contentType);
            response.setContentType(contentType);  
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return response;
    }
}

看完着实不易…到此.