Python:抓取One每天一句话作为随机名言

在很多年前…

我以前看到过不少随机名言,但是碍于当时没有技术不会做,虽然很喜欢.但是也不知道怎么去实现.还好现在技术可以实现,而且也有一个比较好的平台.提供了每天一句话.刚好就用来作名言的数据源了.[地址]

如果要查看效果,可以在页面底部看到相应效果(每次刷新显示的内容都不一样).

还需要…

因为使用了Python的两个库,因此必须安装:requests,BeautifulSoup.这两个库.

安装如下:

1
2
pip install requests
pip install beautifulsoup4

安装之后,就可以使用了.

python Logo
image-2482

简单说一下…

首先,这个程序并没有做到非常”智能”,有些地方使用了print(大概是两个地方).因此,你需要自行复制到某个地方,在继续…..

简单说一下核心的一个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def _getMessage(self):
        messagedata = {}
        for x in range(self.start_index,self.end_index):
            url = 'http://wufazhuce.com/one/%d'
            print("%d-------->正在执行......" % (x))
            r = requests.get(url % (x))
            soup = BeautifulSoup(r.text,"html.parser")
            if soup and soup.select(".one-cita"):
                #print()
                message = (str(soup.select(".one-cita")[0].contents[0])).strip()
                if message:
                    messagedata[str(x)]=message
            soup = None
            r = None
            url = None
        print(messagedata)
        print(len(messagedata))

没错上面这个就是核心函数了,

  1. 首先使用了for循环对数据进行循环读取(self.start_index,self.end_index分别是开始的期号和结束的期号,可以自己设定,具体要看源码(源码在下面)..).
  2. 定义了一个messagedata的dict,dict的key存的是相应期号,value存的是名言内容.(好像这一句才是第一步…)
  3. 在循环中,动态定义url,并且使用了requests第三方库进行网页的获取网页内容.[关于requests]
  4. 拿到内容之后,基本就放心了.
  5. 然后使用了BeautifulSoup对HTML进行解析,话说……BeautifulSoup是个很神奇,很厉害,很霸气的HTML解析库..(反正,正反就是很厉害)
  6. 使用了Python自带的HTML解析引擎,”html.parser”,也有很多第三方的可选.[关于BeautifulSoup]
  7. 这一句可能是最复杂的,message = (str(soup.select(“.one-cita”)[0].contents[0])).strip(),这一句首先是从soup对象中select了class=”.one-cita”的div的数据(select函数是BeautifulSoup提供的使用HTML的class方式选取内容,这一点就方便了很多,select返回的是list,因此使用了[0]获取第一个,跟着使用contents来获取其中的内容,contents继续返回list,接着继续获取[0]),获取到数据之后,str函数将其转换为str类型,并且使用strip()函数对其特殊符号(比如:\t,\n,空格)这些进行清理.返回一个干干净净的文本..OYeah.
  8. 然后就是将期号作为key,名言内容作为value放到dict里面.
  9. 说完了.

源码

源码使用如下:

必须安装requests和BeautifulSoup这两个库,否则..运行不了.

使用步骤如下:

懒得写了,直接看源码里面的吧.

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
#-*- coding=utf-8 -*-
import os
import requests
import time
from bs4 import BeautifulSoup

'''
通过Python的dict生成JavaScript的数组.


'''
class GeneratorJsArray(object):

    def main(self):
                # 内容太多,删掉一堆.
        message = {'26': '跟我去北方吧,逃离爱情的肤浅,南方的江山太妩媚,腐蚀了我的热血。from 左小祖咒《爱情的枪》', '776': '到死之前,我们都是需要发育的孩子,从未长大,也从未停止生长。就算改变不了这个世界,这个世界也别想将我们改变。by 大冰', '275': '青春就是不停地告别,告别就是死亡一点点。by 赵西栋', '30': '很高兴又见到你。by 韩寒', '78': '我不知道庆典之后的日子该怎么过。 by 村上龙', '264': '只有不快乐的人才想知道未来。by 凯特·莫顿', '58': '即使头上长出鹿角,口琴的魔力依然无法停止。今日宜留齐刘海,忌独立小桥。by 张冠仁'}
        print("var mingyan=new Array();")
        for key,value in message.items():
            print("mingyan.push("{\'index\':%d,\'content\':'%s'}");" % (int(key),value))



'''
抓取One的名言.

'''
class One(object):

    def __init__(self):
        self.start_index = 14
        self.end_index = 1384

    def _getMessage(self):
        messagedata = {}
        for x in range(self.start_index,self.end_index):
            url = 'http://wufazhuce.com/one/%d'
            print("%d-------->正在执行......" % (x))
            r = requests.get(url % (x))
            soup = BeautifulSoup(r.text,"html.parser")
            if soup and soup.select(".one-cita"):
                #print()
                message = (str(soup.select(".one-cita")[0].contents[0])).strip()
                if message:
                    messagedata[str(x)]=message
            soup = None
            r = None
            url = None
        print(messagedata)
        print(len(messagedata))

    def main(self):
        print("1.先使用我......:")
        #self._getMessage()

if __name__ == '__main__':
        # 1.先使用One的main函数获取输出结果.
        # 2.将输出结果复制出来,注意是复制...
        # 3.粘贴给GeneratorJsArray类的main函数的message变量......
        # 4.注释掉One的调用.
        # 5.调用GeneratorJsArray类的main函数获取js的输出.
        # 6.新建一个js文件,把刚才输出的结果粘贴进去.
        # 7.搞定.
    gj = GeneratorJsArray()
    gj.main()

另外,我已经生成了一个了.可以直接用的.

调用方式,将下面的内容保存成mingyan.js,然后在页面中创建一个<p id=”showMingyan”></p>,然后使用js:$(“#showMingYan”).html(getMingYanHref());进行调用即可.

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
/**
  随机获取名言.

  author:prd.
  version:2016.7.22
  note:名言均来自[一个](http://www.wufazhuce.com)

  使用示例(关于使用的调用,请参考最底部的函数.):
        1.先引入本js.
        2.在想使用的地方,调用getMingYan()函数即可获取名言.[getMingYanHref()获取可以跳转至One的名言,getMingYanContent():只获取名言内容]
        3.名言中存储为json数据,index对应One的每一期号,content是名言.
        4.请尊重版权,在展示名言的同时,可将名言链接至One.例如:&lt;a href="http://wufazhuce.com/one/14"&gt;是狼是人,日久见心。by 小饭&lt;/a&gt;其中的14为期号.
*/
var mingyan=new Array();
mingyan.push("{'index':1165,'content':'失眠就像是,一个无人认领的梦,一段言无所向的人生,和一场明知故犯的恋情。你不愿这些发生,但你也清楚这些早晚要发生,就像终于盼来了困意,却也迎来了黎明。by 郑执'}");
mingyan.push("{'index':1212,'content':'道路虽然拥挤,却是寂寞的,因为它不是被爱的。 from 《像个孩子》'}");
mingyan.push("{'index':563,'content':'如果我不想被悲伤和怀疑打倒,就非得好好吃饭不可。by 方悄悄'}");
mingyan.push("{'index':1291,'content':'每个人都是孤独发光的星体,至亲、爱人、朋友,构成了我们的星系。星辰会陨落,轨道会迁移,或许再也见不到你。我会记得,你的光芒温暖过我的眼睛。而我,也曾闪耀在你的夜空里。 by 路明'}");
mingyan.push("{'index':855,'content':'我觉得世界上所有事情都在你没有准备好的时候,就开始;在你准备好的时候,就结束了。from《年华似水》'}");
mingyan.push("{'index':1068,'content':'天青色等烟雨,而我在等你。by 方文山'}");
mingyan.push("{'index':435,'content':'不能一直踮着脚爱一个人,重心不稳,撑不了太久的。by 佚名'}");
mingyan.push("{'index':342,'content':'没有深夜痛哭过的人,不足以谈人生。by 高秉涵'}");
mingyan.push("{'index':918,'content':'毁掉我们的不是我们所憎恨的东西,而恰恰是我们所热爱的东西。by 尼尔·波兹曼'}");
mingyan.push("{'index':1258,'content':'信任这种东西有时候挺奇怪的,就是那种你在我背后开了一枪,我依然觉得是枪走了火的感觉。by 暖小团'}");
mingyan.push("{'index':889,'content':'原来生命从头到尾都是一场浪费,你需要判断的仅仅在于,这次浪费是否是“美好”的。后来,当我每做一件事情的时候,我便问自己,你认为它是美好的吗?如果是,那就去做吧,从这里出发,我们去抵抗命运,享受生活。by 吴晓波'}");
mingyan.push("{'index':449,'content':'世上只有一种真正的英雄主义,那就是认清生活的真相后依然热爱生活。by 罗曼·罗兰'}");
mingyan.push("{'index':1164,'content':'有时候我们认为生活背叛了我们,但是很久以后我们才发现,其实是我们自己背叛了自己。 from 《西伯利亚的理发师》'}");
mingyan.push("{'index':717,'content':'所有的悲伤,总会留下一丝欢乐的线索。所有的遗憾,总会留下一处完美的角落。我在冰封的深海,找寻希望的缺口。却在午夜惊醒时,蓦然瞥见绝美的月光。from 《缺口》'}");
mingyan.push("{'index':1279,'content':'不管怎么费尽心力,人会受伤的时候就会受伤。by 村上春树'}");
mingyan.push("{'index':913,'content':'有人说:真正的爱情,背后没有秘密。说这话的人,既不明白爱情,也不明白秘密。from《北京乐与路》'}");
// ... 部分数据.

/**
    随机获取名言.

    直接调用此函数即可.
*/
function getMingYan(){
  return (mingyan[parseInt(Math.random()*(mingyan.length-1)+1)]);
}

/*
  获取名言,并链接至One.
*/
function getMingYanHref(){
  var item = getItem();
  return "&lt;a href='http://wufazhuce.com/one/"+item.index+"' target='_blank'&gt;"+item.content+"&lt;/a&gt;";
}

function getItem(){
  return eval('(' +(mingyan[parseInt(Math.random()*(mingyan.length-1)+1)])+ ')');
}

/*
  只获取内容.
*/
function getMingYanContent(){
  var item = getItem();
  return item['content'];
}

到此.

jQuery:各种提交方式

之前遇到的一个问题

之前遇到过这样一个问题:需要在弹窗里面提交表单,然后在表单提交完之后需要关闭弹窗并刷新当前页面(弹窗里面是iFrame).最早的时候,我是这样处理的:在点击弹窗按钮之后,设置一个setTimeout对弹窗进行关闭.这样就导致了一个问题——有时候弹窗里面的还没处理完,弹窗就关闭了,导致事务失败.数据也就提交失败.

后来换了一种方式对数据提交进行处理(上面那种方式,在提交之后会闪现一个页面[可能是空白页,也可能是其它设置的返回页面,但是在数据很少的情况下,是可以提交成功的]):使用Ajax提交相关数据,然后在success函数里面处理弹窗的关闭与刷新当前页面.

jQuery LOGO
image-2476

看下代码.

源码

下面这段代码就是处理上述问题的(下面这段代码不能提交文件!!!).

1
2
3
4
5
6
7
8
9
10
//jquery 自带的ajax,可以提交普通数据
$.ajax({
                  url : $('#registerForm').prop('action'), // 获取提交地址,必须设置action,此处的prop和attr功能一致,在新版本上推荐使用prop.
                  data : $('#registerForm').serialize(), // 序列化表单数据
                  type : "POST",
                  dataType:"json",
                  success : function(data) {
                    // 成功时的操作.
                  }
      });

经过修改之后,发现效果奇好无比.简直无与伦比的完美……(话说这不是用来形容妹子的么..)

然后,提交文件可以参考下面这种方式(同样是ajax方式).

下面这种方式,必须引入jquery.form.js,不然无法提交

1
2
3
4
5
6
7
8
9
10
11
// jquery.form.js 方式-&gt;可以提交文件.
$("#registerForm").ajaxSubmit({
                        type: "post",
                        url: $("#registerForm").attr("action"),// 必须设置action.
                        success: function (data) {
                                // 成功时的操作......          
                        },
                        error: function (msg) {
                                // 失败时的操作......
                        }
});

注意,如果直接使用$(“#registerForm”).submit();来提交表单,都是会刷新页面的.要达到页面不刷新,就只能用ajax方式提交数据.

比如,需要在提交成功之后,显示一个弹窗,可以像下面这样去实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
&lt;pre class="lang:js decode:true " &gt;
//jquery 自带的ajax,可以提交普通数据
$.ajax({
                  url : $('#registerForm').prop('action'), // 获取提交地址,必须设置action,此处的prop和attr功能一致,在新版本上推荐使用prop.
                  data : $('#registerForm').serialize(), // 序列化表单数据
                  type : "POST",
                  dataType:"json",
                  success : function(data) {
                    // 成功时的操作.
                    alert("恭喜,注册成功!");
                  }
      });
&lt;/pre&gt;

如上即可.

jQuery:对上传文件进行操作

得来..

其实是从昨天的问题引申而来,因为昨天的例子只判断了文件选择是否为空.在当前网络环境下,这显然是不行的…于是今天对代码进行了整理.增加了[文件大小]、[文件后缀]的判断.

对于JavaScript的File的操作,可以参考:地址

html

源码

注意:如果在页面中直接引入iframe,必须给其css设置height属性,否则将影响后面内容的展示.iframe标签不能简写:错误的[<iframe />]!正确写法:[<iframe>lt;/iframe>]

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
/*
                *:此处必须使用live进行事件绑定.
                    因为在118行中,使用了[fileinput.remove();]对元素进行删除.

             */
             $("#file").live("change",function () {        
                  if($.trim($(this).val())==''){//为空的时候不要继续判断.
                         return false;
                   }
                    var filepath = $(this).val();
                    var extStart = filepath.lastIndexOf(".");
                    var fileExt = filepath.substring(extStart, filepath.length).toUpperCase();
                    if ((fileExt != ".BMP" &amp;&amp; fileExt != ".PNG" &amp;&amp; fileExt != ".fileExt" &amp;&amp; fileExt!= ".JPG" &amp;&amp; fileExt != ".JPEG") &amp;&amp; ((fileExt != ".PDF" &amp;&amp; fileExt != ".DOC" &amp;&amp; fileExt != ".DOCX"))) {
                        top.layer.msg("图片限于bmp,png,gif,jpeg,jpg格式,文档仅限于pdf,Word文档格式");
                        $("#upload").prop("disabled",true);
                    }else{
                        var file_size = 0;
                        if ($.browser.msie) {
                            var img = new Image();
                            img.src = filepath;
                            if (img.fileSize &gt; 0) {
                                 if (img.fileSize &gt; 10240) {
                                    top.layer.msg('文件大小不能超过10M,请重新选择!');
                                    $("#upload").prop("disabled",true);
                                 }else{
                                     top.layer.msg("文件大小符合要求!");
                                    $("#upload").prop("disabled",false);
                                 }
                            }
                        } else {
                            file_size = this.files[0].size;
                            var size = file_size / 1024;
                            if (size &gt; 10240) {
                                top.layer.msg("文件大小不能超过10M,请重新选择!");
                                $("#upload").prop("disabled",true);
                            }else{
                                if($("#upload").prop("disabled")){
                                    top.layer.msg("文件符合要求!");
                                }
                                $("#upload").prop("disabled",false);
                            }
                        }
                    }
            });

下面是完整文件,上面一部分则是单独判断的函数:

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
&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt;
&lt;%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;文件上传&lt;/title&gt;
    &lt;meta name="decorator" content="default"/&gt;
    &lt;script type="text/javascript" src="/jquery/jquery.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/jquery/jquery.form.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/layer/layer.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
    &lt;c:if test="${empty list }"&gt;
        $(document).ready(function() {
           
            /*
                *:此处必须使用live进行事件绑定.
                    因为在118行中,使用了[fileinput.remove();]对元素进行删除.

             */
             $("#file").live("change",function () {        
                  if($.trim($(this).val())==''){//为空的时候不要继续判断.
                         return false;
                   }
                    var filepath = $(this).val();
                    var extStart = filepath.lastIndexOf(".");
                    var fileExt = filepath.substring(extStart, filepath.length).toUpperCase();
                    if ((fileExt != ".BMP" &amp;&amp; fileExt != ".PNG" &amp;&amp; fileExt != ".fileExt" &amp;&amp; fileExt!= ".JPG" &amp;&amp; fileExt != ".JPEG") &amp;&amp; ((fileExt != ".PDF" &amp;&amp; fileExt != ".DOC" &amp;&amp; fileExt != ".DOCX"))) {
                        top.layer.msg("图片限于bmp,png,gif,jpeg,jpg格式,文档仅限于pdf,Word文档格式");
                        $("#upload").prop("disabled",true);
                    }else{
                        var file_size = 0;
                        if ($.browser.msie) {
                            var img = new Image();
                            img.src = filepath;
                            if (img.fileSize &gt; 0) {
                                 if (img.fileSize &gt; 10240) {
                                    top.layer.msg('文件大小不能超过10M,请重新选择!');
                                    $("#upload").prop("disabled",true);
                                 }else{
                                     top.layer.msg("文件大小符合要求!");
                                    $("#upload").prop("disabled",false);
                                 }
                            }
                        } else {
                            file_size = this.files[0].size;
                            var size = file_size / 1024;
                            if (size &gt; 10240) {
                                top.layer.msg("文件大小不能超过10M,请重新选择!");
                                $("#upload").prop("disabled",true);
                            }else{
                                if($("#upload").prop("disabled")){
                                    top.layer.msg("文件符合要求!");
                                }
                                $("#upload").prop("disabled",false);
                            }
                        }
                    }
            });
           
            $(".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 &amp;&amp; data.status=='0'){
                                    var idStr = $("#resultIdInfo").val();
                                    idStr = idStr.substring(0,idStr.length-1);
                                    var array = idStr.split(",");
                                    var indexarray = array.indexOf(delid);
                                    if (indexarray &gt; -1) {
                                        array.splice(indexarray, 1);
                                    }
                                    $("#resultIdInfo").val("");
                                    if(array.length&gt;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({
                          type: "post",
                          url: $("#uploadForm").attr("action"),
                          success: function (data) {
                                if(data.status &amp;&amp; data.status=='0'){//成功.
                                    var objinfo = data.result;
                                    if(!checkIdRepeat(objinfo.id)){
                                        var resultValue = $("#resultIdInfo");
                                        resultValue.val(resultValue.val()+objinfo.id+",");
                                        $("#fileInfoTable").append(generatorTrHTML(objinfo.id,objinfo.displayName));
                                    }
                                    fileinput.after(fileinput.clone().val(""));//复制一个新的file.    
                                    fileinput.remove();//删除原有文件域.因为如果需要为文件域绑定事件,必须使用live..
                                }else{
                                    top.layer.msg(data.msg);
                                }                              
                          },
                          error: function (msg) {
                              top.layer.msg("文件上传失败!"+msg);    
                          }
                      });
                      return false;
                 
            })
        });
       
        //拼接html.
        function generatorTrHTML(id,name){
            var html =  "&lt;tr id='"+id+"'&gt;&lt;td&gt;"+name+"&lt;/td&gt;&lt;td&gt;&lt;input type='button' data-id='"
                        +id+"' class='btn btn-danger deletefile' value='删除'/&gt;&lt;/td&gt;&lt;td&gt;&lt;input type='button' onclick='window.open("/viewfile/"+id+"")'  class='btn btn-primary' value='下载'/&gt;&lt;/td&gt;&lt;/tr&gt;";
                   
            return html;
        }
       
        // 检查是否已经存在ID了.
        function checkIdRepeat(fileid){
            var resultValue = $("#resultIdInfo").val();
            if(resultValue &amp;&amp; resultValue.indexOf(fileid)&gt;0){
                return true;
            }
            return false;
        }
        &lt;/c:if&gt;
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form:form id="uploadForm" enctype="multipart/form-data" modelAttribute="document" action="/saveFile" method="post" class="breadcrumb form-search "&gt;
        &lt;c:if test="${empty list and empty see}"&gt;
            &lt;input id="fileUploadType" name="fileUploadType" type="hidden" value="${fileUploadType}"/&gt;
            &lt;input type="text" id="txt" name="txt" class="input"&gt;&amp;nbsp;&amp;nbsp;&lt;input type="button" onmousemove="file.style.pixelLeft=event.x-60;file.style.pixelTop=this.offsetTop;" value="浏览" size="30" onclick="file.click()" class="btn btn-primary"&gt;
            &lt;input type="file" id="file" onchange="txt.value=this.value" name="file" style="height:26px;" class="files"  size="1" hidefocus&gt;
            &lt;input type="button" id="upload" class="btn btn-warning"  &lt;c:if test="${empty fileUploadType}"&gt;disabled="disabled"&lt;/c:if&gt; value="上传"/&gt;&lt;c:if test="${empty fileUploadType}"&gt;&lt;span&gt;文件上传类型为空,暂时不能上传!&lt;/span&gt;&lt;/c:if&gt;
            &lt;input type="hidden" id="resultIdInfo"  /&gt;
        &lt;/c:if&gt;
    &lt;/form:form&gt;
&lt;/body&gt;
&lt;/html&gt;

到此.

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 '''
    &lt;!doctype html&gt;
    &lt;title&gt;Upload new File&lt;/title&gt;
    &lt;h1&gt;Upload new File&lt;/h1&gt;
    &lt;form action="" method=post enctype=multipart/form-data&gt;
      &lt;p&gt;&lt;input type=file name=file&gt;
         &lt;input type=submit value=Upload&gt;
    &lt;/form&gt;
    '''

搞定,关于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
&lt;%@ page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt;
&lt;%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;文件上传&lt;/title&gt;
    &lt;meta name="decorator" content="default"/&gt;
    &lt;script type="text/javascript" src="/jquery/jquery.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/jquery/jquery.form.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/layer/layer.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
    &lt;c:if test="${empty list }"&gt;
        $(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 &amp;&amp; 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 &gt; -1) {
                                        array.splice(indexarray, 1);//在数组中删除相应项
                                    }
                                    $("#resultIdInfo").val("");
                                    if(array.length&gt;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 &amp;&amp; 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 "&lt;tr id='"+id+"'&gt;&lt;td&gt;"+name+"&lt;/td&gt;&lt;td&gt;&lt;input type='button' data-id='"
                        +id+"' class='btn btn-danger deletefile' value='删除'/&gt;&amp;nbsp;&amp;nbsp;&lt;input type='button' onclick='window.open("/viewfile/"+id+"")'  class='btn btn-primary' value='下载'/&gt;&lt;/td&gt;&lt;/tr&gt;";
        }
       
        // 检查是否已经存在ID了.
        function checkIdRepeat(fileid){
            var resultValue = $("#resultIdInfo").val();
            if(resultValue &amp;&amp; resultValue.indexOf(fileid)&gt;0){
                return true;
            }
            return false;
        }
        &lt;/c:if&gt;
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form:form id="uploadForm" enctype="multipart/form-data" modelAttribute="document" action="/saveFile" method="post" class="breadcrumb form-search "&gt;
        &lt;c:if test="${empty list }"&gt;&lt;!-- 如果为空才可以进行文件选择 --&gt;
            &lt;input id="fileUploadType" name="fileUploadType" type="hidden" value="${fileUploadType}"/&gt;
            &lt;input type="file" id="file" name="file" /&gt;
            &lt;input type="button" id="upload" class="default"  &lt;c:if test="${empty fileUploadType}"&gt;disabled="disabled"&lt;/c:if&gt; value="上传"/&gt;&lt;c:if test="${empty fileUploadType}"&gt;&lt;span&gt;文件上传类型为空,暂时不能上传!&lt;/span&gt;&lt;/c:if&gt;
            &lt;input type="hidden" id="resultIdInfo"  /&gt;&lt;!-- 保存文件的ID --&gt;
        &lt;/c:if&gt;
        &lt;table id="fileInfoTable"&gt;
            &lt;c:forEach items="${list }" var="doc"&gt;
                &lt;tr id='${doc.id }'&gt;
                    &lt;td&gt;${doc.displayName }&lt;/td&gt;
                    &lt;td&gt;
                        &lt;input type='button' onclick='window.open("/viewfile/${doc.id }")'  class='btn btn-primary' value='下载'/&gt;
                    &lt;/td&gt;
                &lt;/tr&gt;
            &lt;/c:forEach&gt;
       
        &lt;/table&gt;
    &lt;/form:form&gt;
&lt;/body&gt;
&lt;/html&gt;

第二个文件:后台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 &amp;&amp; fileIds.length &gt; 0) {
            Document document = new Document();
            document.setIdQuery(Arrays.asList(fileIds));
            List&lt;Document&gt; 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 &amp;&amp; StringUtils.isNotBlank(document.getFileUploadType())) {
            List&lt;Document&gt; filePathList = new ArrayList&lt;Document&gt;();
            try {
                filePathList = FileUploadUtil.uploadFile(request, response, document.getFileUploadType());
                if (filePathList.size() &gt; 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-&gt;用户.
   
   
    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 &amp;copy; 2012-2014 &lt;a href="https://github.com/thinkgem/jeesite"&gt;JeeSite&lt;/a&gt; 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 = "&lt;.+?&gt;";
        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("&lt;([a-z]+?)\\s+?.*?&gt;", "&lt;$1&gt;");
    }
   
    /**
     * 替换为手机识别的HTML,去掉样式及属性,保留回车。
     * @param txt
     * @return
     */
    public static String toHtml(String txt){
        if (txt == null){
            return "";
        }
        return replace(replace(Encodes.escapeHtml(txt), "\n", "&lt;br/&gt;"), "\t", "&amp;nbsp; &amp;nbsp; ");
    }

    /**
     * 缩略字符串(不区分中英文字符)
     * @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 &lt;= 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特殊字符,如&amp;nbsp;
        for (int i = 0; i &lt; param.length(); i++) {
            temp = param.charAt(i);
            if (temp == '&lt;') {
                isCode = true;
            } else if (temp == '&amp;') {
                isHTML = true;
            } else if (temp == '&gt;' &amp;&amp; isCode) {
                n = n - 1;
                isCode = false;
            } else if (temp == ';' &amp;&amp; isHTML) {
                isHTML = false;
            }
            try {
                if (!isCode &amp;&amp; !isHTML) {
                    n += String.valueOf(temp).getBytes("GBK").length;
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            if (n &lt;= length - 3) {
                result.append(temp);
            } else {
                result.append("...");
                break;
            }
        }
        // 取出截取字符串中的HTML标记
        String temp_result = result.toString().replaceAll("(&gt;)[^&lt;&gt;]*(&lt;?)",
                "$1$2");
        // 去掉不需要结素标记的HTML标记
        temp_result = temp_result
                .replaceAll(
                        "&lt;/?(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)[^&lt;&gt;]*/?&gt;",
                        "");
        // 去掉成对的HTML标记
        temp_result = temp_result.replaceAll("&lt;([a-zA-Z]+)[^&lt;&gt;]*&gt;(.*?)&lt;/\\1&gt;",
                "$2");
        // 用正则表达式取出标记
        Pattern p = Pattern.compile("&lt;([a-zA-Z]+)[^&lt;&gt;]*&gt;");
        Matcher m = p.matcher(temp_result);
        List&lt;String&gt; endHTML = Lists.newArrayList();
        while (m.find()) {
            endHTML.add(m.group(1));
        }
        // 补全不成对的HTML标记
        for (int i = endHTML.size() - 1; i &gt;= 0; i--) {
            result.append("&lt;/");
            result.append(endHTML.get(i));
            result.append("&gt;");
        }
        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 &lt; 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 &lt; s.length(); i++) {
            char c = s.charAt(i);

            boolean nextUpperCase = true;

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

            if ((i &gt; 0) &amp;&amp; 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&lt;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 &amp;copy; 2012-2014 &lt;a href="https://github.com/thinkgem/jeesite"&gt;JeeSite&lt;/a&gt; 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 &amp;&amp; pattern.length &gt; 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&gt;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 &amp;copy; 2012-2014 &lt;a href="https://github.com/thinkgem/jeesite"&gt;JeeSite&lt;/a&gt; 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&lt;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&lt;Document&gt; 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&lt;Document&gt; uploadFile(HttpServletRequest request,
            HttpServletResponse response, String uploadFileType) throws FileNotFoundException{
        List&lt;Document&gt; filePathList = new ArrayList&lt;Document&gt;();
       
        String strPath = ",webapps,files,"+Document.getTypeName(uploadFileType);
       
        String filepath =   strPath.replace(",", "/");
       
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
       
        Map&lt;String, MultipartFile&gt; fileMap = multipartRequest.getFileMap();
        String fileName = null;
        for (Map.Entry&lt;String, MultipartFile&gt; 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;
    }
}

看完着实不易…到此.

Oracle:更新多行同列不同值

遇到个问题……

这几天遇到个问题,就是在访问后台的时候被强制使用了SSL,所以导致上不了后台.我是如下这样解决的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 下面这个函数在:[wp-includes/functions.php]中
/**
 * Whether to force SSL used for the Administration Screens.
 *
 * @since 2.6.0
 *
 * @staticvar bool $forced
 *
 * @param string|bool $force Optional. Whether to force SSL in admin screens. Default null.
 * @return bool True if forced, false if not forced.
 */
function force_ssl_admin( $force = null ) {
        static $forced = false;

        if ( !is_null( $force ) ) {
                $old_forced = $forced;
                $forced = $force;
                return $old_forced;
        }
        return false;
        //return $forced; 注释掉这一行,然上面直接添加一句 return false;即可.
}

只能这样临时先访问了…

Oracle LOGO
image-2460

关于题目的问题

其实对于题目,说起来也很简单了,大概是这样一个场景:

比如我们正在构建一个信息系统,每个用户每个月有一次抽奖机会,假设我们需要给每次最新的抽奖记录一个标记为1,那么之前的就要标识为0.

好了,上面这个场景就是这个问题.一句话就是:更新某个用户最新一条记录为1,之前的为0.

解决了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
update users_activity
            set lastupdate=(
            case
            when id=#{id} then 1
            when id!=#{id} then 0
            else 0
            end
            ) where userid=#{userid}



--  
update users_activity
            set 要更新的字段=(
            case
            when id=最新记录ID then 1
            when id!=最新记录ID then 0
            else 0
            end
            ) where userid=用户ID

如上,问题解决.