JSP笔记乱(二)

文件传输

XML前后台接受

dom4j 可以解析或者打包XML

1 创建文档对象
Document doc=DocumentHelper.createDocument()返回一个Document对象
2 创建一个根节点
Element root = doc.addElement("root标签>");
3 在根节点下,创建子元素
Element newsEle=root.addElement("子标签");
Element title=newsEle.addElement("字标签中的内容");

4 在子元素中写入内容或者属性
title.addText("我是标题");
title.addAttribute("id","titleOne");
添加了属性
其他的同理

最后,调用文档的方法 doc.asXML();返回一个字符串

在前台可以使用js脚本对传来的数据进行解析
例如

var str = "";
$(data).find(news).each(function(){
     var title = $(this).children("title").text(); //获取每个news标签下的title内容
     var content = $(this).children("content").text(); //获取每个news标签下的content内容
     str = str+title+" "+content+"<br/>"
})
$("#div").html(str);
JSON后台接收

利用fastJson或者其他的网上组件包,可以简便的对从前端传入的json对象进行解析。

ajax中json的获取方法与链接一致,通过request.getParameter();来获取

从前台传入的json对象可能是 单个对象{[a,b,c,d,e]}或{k1:v1, k2:v2},也可能是对象数组( [obj1, obj2 obj3])

如果传递过来的是一个对象,那么采用 fastJSON.jar包中 JSON.parseObject(jsondata,class)
例如

Map<Stirng, String> map = JSON.parseObject(list, Map.class);

如果传递过来的是一个数组,那么使用List list = JSON.parseArray(jsondata);解析不当将会出现错误

在java后台是date对象,经过JSON.parse() 方法后,前台得到的是秒

jQuery Pagination Ajax分页使用

Pagination插件是一款免费开源的jQuery插件其官网 http://paginationjs.com/index.html,在github上也开源了。在这个的首页上有许多的demo演示。接下来介绍如何使用这个插件,以及如何实现Ajax分页。

HTML部分,需要指定两个div,其id属性为下,得到的数据将放入数据容器中,分页按钮在分页容器中

<div id="data-container"></div>
<div id="pagination-container"></div>

一般的使用
如果不实现异步请求,那么需要获取所有需要分页的数据,然后会自动交给分页工具,根据设置的每页显示pageSize,自动计算页码等信息,需要传入显示的template,放置数据。

Pagination Ajax使用
$('#pagination-container').pagination({
    dataSource: "servlet/ServletAsync?op=pagingNews",  //异步请求的地址
    locator:"data",  //当返回对象是object时,不会直接丢给pagination处理,而是要经过这个定位数据位置,默认是整个数据data
    totalNumber:total,  //总记录数,异步请求时必须填写
    showGoInput: true, //是否显示跳页输入框
    showGoButton: true, //是否显示跳页按钮
    pageSize:5, //每页显示个数
    alias: {
        pageNumber: 'curPage',  //
        pageSize: 'everyPage'
    },
    formatGoInput: "<input type='text' class='J-paginationjs-go-pagenumber' >",
    // 每次翻页时触发的回调函数
    callback: function(data, pagination ) { //data当前页的数据,pagination当前页的信息
    var html = simpleTemplating(data);  //显示数据的模板
        $('#data-container').html(html);  //添加到页面当中
    }
});
//数据要放入的模板,例如我这里是放入到表格中,data为每次ajax获取的数据
function simpleTemplating(data) {
    var html = "<table>";
    var d = new Date();
    $.each(data, function(index, item){
        html += "<tr>";
        html += "<td>"+ item.newsid+"</td>";
        html += "<td>"+ item.newstypename+"</td>";
        html += "<td>"+ item.title+"</td>";
        d.setTime(item.newsTime);
        html += "<td>"+ d.toLocaleDateString()+"</td>";
        html += "</tr>";
    });
    html += "</table>";
    return html;
}
未解决的一个小问题

Pagination插件要实现异步请求的话,必须知道总的记录数,意味着你必须要多请求一次。因此,当访问的数据量很大的时候,该插件的响应时间会有点长。

文件的上传和下载

使用jsp+servlet的方式(见慕课教程)

使用jsp+servlet实现文件的上传和下载的大体思路如下:

文件的上传

对于上传的文件,我们需要读取它,然后放置到一个临时文件内(为什么不直接存取呢?因为上传的流中除了我们想要的信息外,还有其他信息),获取上传的文件名,建立一个输出流,将临时文件中的内容写入到服务器下的文件中,然后删除文件。具体代码实现如下(在servlet中)

InputStream inp = request.getInputStream();
String tempFile = "D:/web/tempFile";
File temp = new File(tempFile);
if (!temp.exists()){
    temp.createNewFile();
}

FileOutputStream fos = new FileOutputStream(temp);
byte[] bts = new byte[1024];
int n =0;
while(( n= inp.read(bts)) != -1 ){
    fos.write(bts, 0, n);
}

fos.close();
inp.close();

RandomAccessFile ras = new RandomAccessFile(temp, "r");
ras.readLine();
//针对文件名含有中文时,进行的转码
String head = new String(ras.readLine().getBytes("ISO-8859-1"),"utf-8");
//文件名可能为“/xxxx”或者是 "xxxx",因此使用两种获取文件名的方式
int beginIndex = head.lastIndexOf("/")+1; 
if (beginIndex==0){
    beginIndex = head.lastIndexOf("=")+2;
}
int endIndex = head.lastIndexOf("\"");
//获取文件名
String fileName = head.substring(beginIndex, endIndex);
System.out.println(fileName);

//文件的开始位置在head下一行开始的“换行符”  结束位置在倒数第一个换行符
ras.seek(0);
long startPos =0L;
int j = 1;
// 文件的内容通过 firebug可以发现是从第四行开始的,以换行符开始
while((n=ras.readByte())!= -1 && j<=4){
    if ( n == '\n' ){
        startPos = ras.getFilePointer();
        j++;
    }
}
startPos = ras.getFilePointer() - 1;

//获取文件截止的位置
ras.seek(ras.length());
long endPos = ras.getFilePointer();
int k =1;
//内容结束时倒数第二行
while(endPos >=0 && k<=2){  
    endPos--;
    ras.seek(endPos);
    if( ras.readByte()== '\n'){
        k++;
    }
}
endPos = endPos -1;


//保存文件到我们的服务器路径下
String path = getServletContext().getRealPath("/")+"load";
File f = new File(path);
if (!f.exists()){
    f.mkdir();
}
File saveFile = new File(path, fileName);
RandomAccessFile saveRas = new RandomAccessFile(saveFile, "rw");
//将指针放在内容开始的地方
ras.seek(startPos);  
while(startPos<endPos){
    saveRas.write(ras.readByte());
    startPos=ras.getFilePointer();
}
saveRas.close();
ras.close();
temp.delete();//删除临时文件
文件的下载

首先我们需要从请求中获取要下载的文件名,然后找出在服务器上的绝对路径,创建出file对象,如果文件不存在,返回一个错误的信息,文件存在,设置response的编码格式和响应头,然后我们从服务器内读取文件,写入到servletOutputStream 中。然后关闭流。代码实现如下

request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
/*获得请求的文件名*/
String fileName = request.getParameter("filename");
System.out.println(fileName);
/*得到在服务器下的存储路径*/
String path = getServletContext().getRealPath("/")+"load\\"+fileName;
System.out.println(path);
/*创建File对象*/
File f = new File(path);
if (f.exists()){
    /*设置编码格式*/
    response.setContentType("application/x-msdownload");
    /*由于HTTP头部的默认编码为ISO-8859-1而我们上传文件于下载文件过程中,提取到的文件名都要通过HTTP头部。
所以我们需要在上传的时候对提取到的文件名进行转码为UTF-8,然后在下载时我们也要进行反向转码为ISO-8859-1.*/
    String temp = new String(fileName.getBytes("utf-8"),"ISO-8859-1");
    /*设置请求头,表明以附件的形式进行下载*/
    response.setHeader("Content-Disposition", "attachment; filename=\""+temp+"\"");
    System.out.println(response.getHeader("Content-Disposition"));
    InputStream ins = new FileInputStream(f);
    ServletOutputStream output = response.getOutputStream();
    byte[] bts = new byte[1024];
    int n=0;
    while((n = ins.read(bts)) != -1 ){
        output.write(bts, 0, n);
    }
    output.close();
    ins.close();
}else {
    System.out.println("文件不存在");            
}
使用SmartUpload插件来进行下载和上传

上传的input控件必须要有name属性,其值可以是任意。
如果文件不存在,除了可以创建文件之外,也可以创建文件夹

String realPath=this.getServletContext().getRealPath("/")+"loads";RealPath将会获得文件在服务器的绝对路径,如果你工程名为web 直接是 localhost:8080/web/
需要创建一个SmartUpload对象出来
并实例化

String filename = request.getParameter("filename");
SmartUpload up = new SmartUpload();
up.initialize(getServletConfig(), request, response);
up.upload();
up.save("/load/"); 设置你的保存路径

在数据库中存储的,应该是保存路径+文件名, 利用文件名寻找

通过点击文件的链接来实现下载文件

<a href="*servlet*?filename=xxxx">下载xxxx</a>

在后台的servlet中

String filename = request.getParameter("filename");
SmartUpload up = new SmartUpload();
up.initialize(getServletConfig(), request, response);
up.downloadFile("/load/"+filename);    //"填写的是当前context下的文件夹和文件名"
up.setContentDisposition(null);  //设置不再网页打开,而是以插件下载

JNDI与连接池

在tomcat下conf文件夹内context.xml文件下的context标签中设置如下设置(如果是在serve.xml中配置则是对于当前的项目有效)

<!-- JNDI -->
<Environment name="testJNDI" value="hello JNDI" type="java.lang.String" />
<!-- JNDI -->
<Resource
name="jdbc/news"
  auth="Container" //应用管理者 Containertomcat容器 或者 Application web应用管理 
  type="javax.sql.DataSource"  
  maxActive="50" //最大活跃的链接数
  maxIdle="10" //最大空闲链接
  maxWait="10000"  //最大等待时间
  username="root"
  password="123456"
  driverClassName="com.mysql.jdbc.Driver" //数据库连接驱动
  url="jdbc:mysql://127.0.0.1:3306/news?characterEncoding=utf-8"
  />

使用JNDI必须在服务器容器内使用,也就是说,在一般的java main方法是无法运行的。

Context context = new InitialContext();    /*javax.naming 包*/
DataSource ds =(DataSource) context.lookup("java:comp/env/jdbc/news");  /*Datasource java.sql包中*/
conn =ds.getConnection();

过滤器

过滤,顾名思义,对请求内容进行筛选,让符合一定规则的请求,继续执行,不符合的则挡在外面。

一个过滤器的产生和消亡需要经历4个阶段
实例、初始化(在服务器启动的时候)、过滤和销毁(在服务关闭的时候)。

如果存在多个过滤器,那么他们实例和初始化的顺序是随机的,与在web.xml中书写的顺序无关,书写顺序只与他们的触发顺序有关

使用服务器,需要再javaWeb工程下配置web.xml文件添加上的内容标签为

<filter>
    <filter-name>过滤器名</filter-name>
    <filter-class>实现类</filter-name>
</filter>
<filter-mapping>
    <filter-name>过滤器名</filter-name>
    <!--  例如"/*"表示对所有文件进行过滤操作,包括图片和其他; "/dir/*"表示对某个文件夹下的所有文件过滤;  "*.html"表示过滤HTML文件  -->
    <url-pattern>要过滤的文件</url-pattern>  
</filter-mapping>

这里需要解释一下过滤的意思。过滤其实是一种控制,比方说设置过滤的文件为a.html,那么所有访问a.html的请求,都必须要经过过滤器的审核,然后才真正的进入了a.html文件。

创建一个过滤器要求必须实现javax.servlet.Filter接口,重写其中的init(); destroy(); 和 doFilter()方法,在doFilter方法中有3个参数,其中2个ServletRequest和ServletResponse是 servlet中 HttpServletRequest和HttpServletResponse的父类,因此可以使用其中的大部分方法,特定情况下,也是可以类型转换为子类对象。
过滤结束后,放行是通过FilterChain的doFilter()方法,可以将请求送入下一个过滤器,或者阻挡返回,或者传送到指定路径
doFilter(ServletRequest arg0, ServletResponse arg1)

过滤器链如果下一个没有过滤器了,那么chain就会送至目标url 而什么都不做则页面空白。

过滤器的url-pattern 无法实现同时对路径过滤和对文件类型过滤 比如 /admin/*.jsp 这样是不合法的,实现这个需求的方法是在过滤器中做操作

可以在filter标签中继续配置一个针对转发的标签

指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个子元素用来指定 Filter 对资源的多种调用方式进行拦截。

子元素可以设置的值及其意义

  1. REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
  2. INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
  3. FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
  4. ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值