JSP笔记乱(二)

来源:互联网 发布:网络信息员岗位职责 编辑:程序博客网 时间:2024/05/21 09:40

文件传输

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 --><Resourcename="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