美文网首页
JavaEE学习day-58:分页技术和文件上传下载

JavaEE学习day-58:分页技术和文件上传下载

作者: 开源oo柒 | 来源:发表于2019-10-17 21:25 被阅读0次

    一、分页技术

    1.分页的作用:

    数据量大,一页容不下
    后台查询部分数据而不是全部数据
    降低带宽使用,提高访问速度

    2.实现思路:

    • MVC需要每个层次都参与分页。
    • Dao层:

    (1)查询记录的总条数;
    (2)查询每页展示固定条的记录;
    (3)在查询每页展示固定记录的基础上添加条件查询。

    • 业务层:

    对控制层的方法进行简单调用;

    • Servlet层:

    (1)获取页面的页数和每页的记录条数;
    (2)调用业务层处理;
    (3)使用请求转发;

    3.PageBean的使用:

    • 基本属性:

    (1)每页几条记录size 可以有默认值5;
    (2)当前页号 index 可以有默认值1;
    (3)记录总数totalCount:没有默认值,需查询数据库获取真正记录总数。
    (4)分页Bean还可以放要查询的数据 protected List<T> list。

    • 其他属性:

    (1)一共多少页 :totalPageCount=totalCount/size+1;
    (2)上一页 index-1 当前页1,上一页1;
    (3)下一页 index+1 当前页是最后一页 下一页:还是最后一页。
    (4)分页Bean还可以放页码列表 [1] 2 3 4 5 private int[] numbers。

    • pageBean代码:
    package com.bjsxt.util;
    
    import java.util.List;
     * @author Administrator
     *
     * @param <T>
     */
    public class PageBean<T> {
        private int size = 5;//每页显示记录  //
        private int index = 1;// 当前页号      
        private int totalCount = 0;// 记录总数      ok
        
        private int totalPageCount = 1;// 总页数   ok
        
        
        
        private int[] numbers;//展示页数集合  //ok
        protected List<T> list;//要显示到页面的数据集  
    
        /**
         * 得到开始记录
         * @return
         */
        public int getStartRow() {
    
            return (index - 1) * size;
        }
    
        /**
         * 得到结束记录
         * @return
         */
        public int getEndRow() {
            
            return index * size;
        }
    
        /**
         * @return Returns the size.
         */
        public int getSize() {      
            return size;
        }
    
        /**
         * @param size
         * The size to set.
         */
        public void setSize(int size) {
            if (size > 0) {
                this.size = size;
            }
        }
        /**
         * @return Returns the currentPageNo.
         */
        public int getIndex() {
            if (totalPageCount == 0) {
                
                return 0;
            }
            
            return index;
        }
    
        /**
         * @param currentPageNo
         * The currentPageNo to set.
         */
        public void setIndex(int index) {
            if (index > 0) {
                this.index = index;
            }
        }
    
        /**
         * @return Returns the totalCount.
         */
        public int getTotalCount() {
            return totalCount;
        }
    
        /**
         * @param totalCount
         *  The totalCount to set.
         */
        public void setTotalCount(int totalCount) {
            if (totalCount >= 0) {
                this.totalCount = totalCount;
                setTotalPageCountByRs();//根据总记录数计算总页�?
            }
        }
    
        
        public int getTotalPageCount() {
            return this.totalPageCount;
        }
    
        /**
         * 根据总记录数计算总页�?
         * 5   
         * 20    4
         * 23    5
         */
        private void setTotalPageCountByRs() {
            if (this.size > 0 && this.totalCount > 0 && this.totalCount % this.size == 0) {
                this.totalPageCount = this.totalCount / this.size;
            } else if (this.size > 0 && this.totalCount > 0 && this.totalCount % this.size > 0) {
                this.totalPageCount = (this.totalCount / this.size) + 1;
            } else {
                this.totalPageCount = 0;
            }
            setNumbers(totalPageCount);//获取展示页数集合
        }
    
        public int[] getNumbers() {
            return numbers;
        }
        
        /**
         * 设置显示页数集合
         * 
         * 默认显示10个页码
         * 41  42  43  44    [45 ]   46  47  48  49  50
         * 
         * 
         *  [1] 2  3 4  5 6 7 8  9  10
         *  
         *  41  42  43  44    45    46  47  [48]  49  50
         * @param totalPageCount
         */
        public void setNumbers(int totalPageCount) {
            if(totalPageCount>0){
                //!.当前数组的长度
                int[] numbers = new int[totalPageCount>10?10:totalPageCount];//页面要显示的页数集合
                int k =0;
                //
                //1.数组长度<10   1 2 3 4 ....   7
                //2.数组长度>=10
                //     当前页<=6  1 2 3 4    10
                //     当前页>=总页数-5           ......12 13 14 15  
                //     其他                                5  6  7 8   9 当前页(10)  10  11 12  13
                for(int i = 0;i < totalPageCount;i++){
                    //保证当前页为集合的中�?
                    if((i>=index- (numbers.length/2+1) || i >= totalPageCount-numbers.length) && k<numbers.length){
                        numbers[k] = i+1;
                        k++;
                    }else if(k>=numbers.length){
                        break;
                    }               
                }
                
                this.numbers = numbers;
            }
            
        }
        
        public void setNumbers(int[] numbers) {
            this.numbers = numbers;
        }
    
        public List<T> getList() {
            return list;
        }
    
        public void setList(List<T> list) {
            this.list = list;
        }
    
    
    /*
        public static int getTotalPageCount(int iTotalRecordCount, int iPageSize) {
            if (iPageSize == 0) {
                return 0;
            } else {
                return (iTotalRecordCount % iPageSize) == 0 ? (iTotalRecordCount / iPageSize) : (iTotalRecordCount / iPageSize) + 1;
            }
        }*/
    }
    

    4.实现分页的后台操作:

    • 控制层:

    (1) 获取当前页号;
    (2)将当前页号给PageBean;
    (3)传递PageBean到业务层;

    package com.bjsxt.servlet;
    
    import java.io.IOException;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.bjsxt.entity.Student;
    import com.bjsxt.service.StudentService;
    import com.bjsxt.service.impl.StudentServiceImpl;
    import com.bjsxt.util.PageBean;
    
    public class ShowAllServlet extends HttpServlet {
    
        
        public void service(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            //接收页面数据
            //页码
            String sindex = request.getParameter("index");
            int index = 0;
            try {
                index = Integer.parseInt(sindex);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            //条数
            String sizes = request.getParameter("size");
            int size = 5;
            try {
                size = Integer.parseInt(sizes);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            //条件查询名字
            String name = request.getParameter("name");
            //分数
            String minScores = request.getParameter("minScore");
            double minScore = 0;
            if(minScores==null){
                minScores="";
            }
            try {
                minScore=Double.parseDouble(minScores);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            
            PageBean bean = new PageBean();
            bean.setIndex(index);
            bean.setSize(size);
            //调用业务层
              StudentService service = new StudentServiceImpl();
              
             service.findStu(bean,name,minScore);
              
             request.setAttribute("bean",bean);
             request.setAttribute("name", name);
             request.setAttribute("minScore", minScores);
             
             
            //跳转页面
            request.getRequestDispatcher("/jsp/showAll.jsp").forward(request, response); 
        }
    
    
    }
    
    • 业务层:

    (1)获取记录总数;
    (2)使用记录总数计算PageBean其他属性值;
    (3)调用数据访问层获取当前页数据并给PageBean;

    package com.bjsxt.service.impl;
    
    import java.util.List;
    
    import com.bjsxt.dao.StudentDao;
    import com.bjsxt.dao.impl.StudentDaoImpl;
    import com.bjsxt.entity.Student;
    import com.bjsxt.service.StudentService;
    import com.bjsxt.util.PageBean;
    
    public class StudentServiceImpl implements StudentService {
    
        private StudentDao stuDao = new StudentDaoImpl();   
    
        public List<Student> findAll() {        
            return this.stuDao.findAll();
        }
        
        public void findStu(PageBean<Student> pageBean, String name, double minScore) {
            //查询数据库中符合查询条件的记录总数
            int totalCount = stuDao.findCount();
            System.out.println("count="+totalCount);
            //使用记录总数计算PageBean中其他的属性(totalCount,totalPageCount,numbers)
            pageBean.setTotalCount(totalCount);
            //调用Dao层获取指定页的学生数据;并放入pageBean的list属性
            int start = pageBean.getStartRow();
            int end = pageBean.getEndRow();
            List<Student> list = stuDao.findStu(start, end, name, minScore);
            pageBean.setList(list);
            
        }
    
        public void findStu(PageBean<Student> pageBean) {
            //查询数据库获取总记录数
            int totalCount = stuDao.findCount();
            System.out.println("count="+totalCount);
            //使用总记录数计算PageBean中的其他属性(totalCount,totalPageCount,numbers)
            pageBean.setTotalCount(totalCount);
            
            //调用Dao层获取指定页的学生数据;并放入pageBean的list属性
            int start = pageBean.getStartRow();
            int end = pageBean.getEndRow();
            List<Student> list = stuDao.findStu(start, end);
            pageBean.setList(list);
                    
        }
        
    }
    
    
    • 数据访问层:

    (1)分页查询语句:
    select * from (select rownum r,e2.* from
    ( select e.* from student e order by score desc) e2
    where rownum<="+end+" ) where r>start;
    (2)查询记录总条数:
    select count() from student where 1=1;
    (3)MySQL中的分页使用的limit关键字 (limit 起始位置, 分页单位)
    分页单位为5,第一页 起始位置=(当前页-1)
    分页单位
    select * from products order by pid limit 0,5
    -- 分页单位为5,第二页
    select * from products order by pid limit 5,5
    -- 分页单位为5,第三页
    select * from products order by pid limit 10,5

    (4)代码示例:

    public int findCount(String name, double minScore) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            int count = 0;
            try {
                StringBuilder sql = new StringBuilder("select count(*) from student where 1=1 ");
                if(name!=null&&!"".equals(name)){
                    sql.append("and name like '%"+name+"%'");
                }
                if(minScore>0){
                    sql.append("and score >= "+minScore);
                }
                conn = DBUtil.getConnection();
                ps = conn.prepareStatement(sql.toString());
                rs = ps.executeQuery();
                if(rs.next()){
                    count = rs.getInt("cnt");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                DBUtil.closeAll(rs, ps, conn);
            }
            
            return count;
        }
    
    public List<Student> findStu(int start, int end, String name, double minScore) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            List<Student> list = new ArrayList<Student>();
            
            StringBuilder sql2 = new StringBuilder("select  stu.* from student stu where 1=1");
            if(name!=null&&!"".equals(name)){
                sql2.append("and name like '%"+name+"%'");
            }
            if(minScore>0){
                sql2.append("and score >= "+minScore);
            }
            String sql = "select  * from (select rownum rn,stu2.* "
                    + "from ("+sql2.toString()+") stu2 "
                    + "where rownum <="+end+" ) "
                    + "where rn >"+start;
            
            try {
                conn = DBUtil.getConnection();
                ps  = conn.prepareStatement(sql);
                rs = ps.executeQuery();
                while(rs.next()){
                    Student stu = new Student();
                    stu.setId(rs.getInt("id"));
                    stu.setName(rs.getString("name"));
                    stu.setAge(rs.getInt("age"));
                    stu.setScore(rs.getDouble("score"));
                    list.add(stu);
                    
                }
                
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                DBUtil.closeAll(rs, ps, conn);
            }
            
            return list;
        }
        
    
    • 视图层:

    (1)视图层显示分页;
    (2)使用JSTL/EL完成分页数据显示;

    需求
    • 代码示例:
    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>查询并显示所有学生信息</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
        <script type="text/javascript">
            function changeIndex(index){
                location.href = "servlet/ShowAllServlet?index="+index;
            }
            function changeIndex(size){
                location.href = "servlet/ShowAllServlet?size="+size;
            }
            function change2(index,size){
                location.href="servlet/ShowAllServlet?index="+index+"&size="+size;
                //document.forms[0].action="servlet/ShowAllServlet?index="+index+"&size="+size;
                //document.forms[0].submit();
            }
            function change(index,size){
                document.forms[0].index.value = index;
                document.getElementById("size").value = size;
                document.forms[0].submit();
            }
        </script>
    
      </head>
      
      <body> 
        <!-- 显示所有学生   /stumanager/    -->
        <form action="servlet/ShowAllServlet" method="post">
            <table align="center">
                <tr>
                    <td>姓名</td>
                    <td>
                        <input type="text" name="name" value="${name }" />
                        <input type="hidden"  name="index" value="">
                        <input type="hidden" id="size" name="size">
                    </td>
                    <td>分数</td>
                    <td>
                        <input type="text" name="minScore" value="${minScore }" />
                    </td>
                    <td>
                        <input type="submit" value="查询" />
                    </td>
                </tr>
            </table>
        </form>
        <hr />
        <table align="center" border="1" width="60%">
            <tr>
                <th>学生 编号</th>
                <th>学生姓名</th>
                <th>学生年龄</th>
                <th>学生成绩</th>
                
                <th>更新操作</th>
                <th>删除操作</th>
            </tr>
            <c:forEach items="${bean.list }" var="stu" varStatus="vs">
                <tr>
                    <td>${stu.id }</td>
                    <td>${stu.name }</td>
                    <td>${stu.age }</td>
                    <td>${stu.score }</td>
                    
                    <td><a href="servlet/ShowAllServlet">更新</a></td>
                    <td><a href="servlet/ShowAllServlet">删除</a></td>
                </tr>
            </c:forEach>
            <!--  <tr>
                <td colspan="11" align="center">
                <a href="javascript:change(1,${bean.size })">首页</a>&nbsp;&nbsp;
                <a href="servlet/ShowAllServlet?index=${bean.index-1 }">上一页</a>&nbsp;&nbsp; 
                1&nbsp;  2&nbsp;  3&nbsp;  4&nbsp; 5&nbsp;  
                <a href="servlet/ShowAllServlet?index=${bean.index+1 }">下一页</a> &nbsp;&nbsp; 
                <a href="servlet/ShowAllServlet?index=${bean.totalPageCount }">尾页 </a>&nbsp;&nbsp; 
                每页${bean.size }条记录&nbsp;&nbsp;  
                跳转到第几页&nbsp;&nbsp;
                共${bean.totalCount }条记录&nbsp;&nbsp;
                </td>
            </tr> -->
            <tr>
                <td colspan="11" align="center">
                 <a href="javascript:change(1,${bean.size })">首页</a> &nbsp;&nbsp;
                    <c:if test="${bean.index !=1 }">
                        <a href="javascript:change(${bean.index-1 },${bean.size })">上一页  </a>&nbsp;&nbsp;
                    </c:if>
                    <c:if test="${bean.index ==1 }">
                        上一页 &nbsp;&nbsp;
                    </c:if>
                    <c:forEach items="${bean.numbers }" var="num">
                        <c:if test="${num ==bean.index }"> 
                            [<a href="javascript:change(${num },${bean.size })">${num }</a>]&nbsp;
                        </c:if>
                        <c:if test="${num != bean.index }">
                            <a href="javascript:change(${num },${bean.size })">${num }</a>&nbsp;
                        </c:if>
                    </c:forEach>
                    <c:if test="${bean.index != bean.totalPageCount }">
                        <a href="javascript:change(${bean.index+1 },${bean.size })">下一页</a>&nbsp;&nbsp;
                    </c:if>
                    <c:if test="${bean.index == bean.totalPageCount }">
                        下一页 &nbsp;&nbsp;
                    </c:if>             
                     <a href="javascript:change(${bean.totalPageCount },${bean.size })">末页</a>&nbsp;&nbsp; 
                    每页
                        <select onchange="change(${bean.index},this.value)">
                            <c:forEach begin="5" end="20" step="5" var="i">
                                <c:if test="${i==bean.size }">
                                    <option value="${i }" selected="selected">${i }</option>
                                </c:if>
                                <c:if test="${i!=bean.size }">
                                    <option value="${i }">${i }</option>
                                </c:if>
                            </c:forEach>
                        </select>
                    条记录&nbsp;&nbsp;
                     直接跳到第 
                    <select onchange="change(this.value,${bean.size})">
                        <c:forEach  begin="1"  end="${ bean.totalPageCount }" var="num">
                            <c:if test="${num == bean.index }">  
                                <option value="${num }" selected="selected">${num }</option>
                            </c:if>
                            <c:if test="${num != bean.index }">
                                <option value="${num }">${num }</option>
                            </c:if>
                        </c:forEach>
                    </select> 
                      页 &nbsp;&nbsp;
                                     
                      共${bean.totalCount }条记录
                </td>
            </tr>
        </table>
       
      </body>
    </html>
    

    4.新增技能点:

    • 需求:点击页码超链接的同时要提交表单。

    实现1:修改form的action属性
    • document.forms[0].action="servlet/ShowAllServlet?index="+index+"&size="+size;
    实现2:给表单添加hidden属性,表示index和size
    • <input type="hidden" id="index" name="index" >
    • <input type="hidden" id="size" name="size" >
    • document.getElementById("index").value=index;
    • document.getElementById("size").value=size;

    二、文件的上传和下载

    1.文件的上传:

    • 需求:

    上传文件到服务器,不保存相关信息到数据库,只涉及视图层和控制层。

    • 实现思路:

    (1)稍微复杂一些 直接使用Servlet实现有难度,一般使用apache commons组件中commons-fileUpload组件,大大降低操作的难度。
    • commons-fileUpload离不开commons-io组件;
    • commons-fileUpload的常用类;
    • FileItemFactory DiskFileItemFactory:工厂类,生产FileItem;
    • FileItem:每个表单项都会被封装成一个FileItem对象;
    • ServletFileUpload:实现上传操作,将表单数据封装到FileItem中。

    • 实现步骤:

    (1)添加jar包:
    commons-fileupload.jar commons-io.jar;
    (2)视图层:
    表单提交方式: method="post";enctype="multipart/form-data";
    标签:<input type="file" name="photo"></br>;
    (3)控制层:
    a.创建FileItemFactory对象;
    b.创建ServletFileUpload对象;
    c.通过ServletFileUpload对象实现上传操作;将客户端一个个表单项封装到一个个FileItem中;
    d.遍历各个FileItem(相当于对各个表单项进行处理);
    e.指定上传的文件夹(Tomcat的webApps目录下;Tomcat的webApps目录之外)。

    • 控制层代码:
    package com.bjsxt.servlet;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import java.util.UUID;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileItemFactory;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    import com.bjsxt.entity.Students;
    import com.bjsxt.service.StudentService;
    import com.bjsxt.service.impl.StudentServiceImpl;
    
    public class AddServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
    
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // request.setCharacterEncoding("utf-8");
            // 获取数据
            // String name= request.getParameter("name");
            // int age=Integer.parseInt(request.getParameter("age"));
            // Double score=Double.parseDouble(request.getParameter("score"));
    
            // 1.创建FileItemFactory对象
            FileItemFactory factory = new DiskFileItemFactory();
            // 2.创建ServletFileUpload对象
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setHeaderEncoding("utf-8");// file表单的文件乱码
    
            // 限制上传的单个和所有文件的大小
            upload.setFileSizeMax(5 * 1024 * 1024);// 单个文件大小
            upload.setSizeMax(5 * 1024 * 1024);// 总文件上限
    
            // 3.通过ServletFileUpload对象实现上传操作;将客户端一个个表单项封装到一个个FileItem中
            List<FileItem> itemList = null;
            try {
                itemList = upload.parseRequest(request);
            } catch (FileUploadException e) {
                e.printStackTrace();
                request.setAttribute("mess", "文件不能超过20kb!");
                request.getRequestDispatcher("/add.jsp").forward(request, response);
                return;
            }
    
            String name = null;
            int age = 0;
            double score = 0;
            String realName = null;
            String photoName = null;
            String photoType = null;
            
            // 4.遍历各个FileItem(相当于对各个表单项进行处理)
            for (int i = 0; i < itemList.size(); i++) {
                // 取出第一个表单项
                FileItem item = itemList.get(i);
                String fielName = item.getFieldName();
                // 对各个表单项进行处理(普通表单项和文件表单项要分开处理)
                if (item.isFormField()) {
                    // name
                    if ("name".equals(fielName)) {
                        name = item.getString("utf-8");// 非文件表单项乱码问题
                    }
                    // age
                    if ("age".equals(fielName)) {
                        age = Integer.parseInt(item.getString());
                    }
                    // score
                    if ("score".equals(fielName)) {
                        score = Double.parseDouble(item.getString());
                    }
                } else {// 文件表单项
                    if ("photo".equals(fielName)) {
                        // 限制上传的文件类型:只上传jpg,jpeg和gif文件
                        String contentType = item.getContentType();
                        photoType = item.getContentType();
                        if(!"image/jpeg".equals(contentType) && !"image/gif".equals(contentType)){
                            request.setAttribute("mess", "只能上传jpg和gif文件");
                            request.getRequestDispatcher("/add.jsp").forward(request, response);
                            return;
                        }
                        // 5.指定上传的文件夹(Tomcat的webApps目录下;Tomcat的webApps目录之外)
                        String realPath = this.getServletContext().getRealPath("/upload");
                        File dir = new File(realPath);
                        // 判断文件夹是否存在,创建
                        if (!dir.exists()) {
                            dir.mkdirs();
                        }
                        // 指定上传的文件名
                        realName = item.getName();// 原文件名
                        // 防止文件的同名覆盖,上传到服务器端的文件重新命名
                        UUID uuid = UUID.randomUUID();
    //                  System.out.println("realName.lastIndexOf(\".\")"+realName.lastIndexOf("."));
                        String extName = realName.substring(realName.lastIndexOf("."));
                        photoName = uuid.toString() + extName;
                        File file = new File(dir, photoName);
                        try {
                            item.write(file);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
    
                }
            }
    
            Students stu = new Students(name, age, score, realName, photoName, photoType);
            // 调用Biz 方法
            StudentService stuBiz = new StudentServiceImpl();
            int n = stuBiz.save(stu);
            // 页面跳转
            if (n != 0) {
                // 重定向:/后面要跟上下文路径
                response.sendRedirect(request.getContextPath() + "/servlet/ShowAllServlet");
            } else {
                request.setAttribute("mess", "添加失败!");
                request.getRequestDispatcher("/add.jsp").forward(request, response);
            }
    
        }
    
    }
    
    • 视图层代码:
     <form action="servlet/AddServlet" method="post" enctype="multipart/form-data" >        
            用户名:<input type="text" name="name"><br>
            年龄:<input type="text" name="age"><br>
            分数:<input type="text" name="score"><br> 
            照片:<input type="file" name="photo" /> <br>    
            
            <input type="submit" value="提交">    
        </form>
    

    2. FileItem的常用方法:

    (1)item.isFormField() 如果是普通表单项 true,如果是file表单项,false;
    (2)item.getFieldName() 表单项的name属性;
    (3)item.getString() 普通表单项的值,file表单项就是file的内容;
    (4)item.getString(“utf-8”) 解决普通表单项的中文乱码问题;
    (5)item.getName() 普通表单项就是null,file表单项就是文件的名称;
    (6)item.getContentType() 普通表单项是null,file表单项就是文件的类型;
    (7)item.getSize():表单项内容长度;

    • 解决乱码问题:

    (1)解决file表单项中文乱码问题:
    upload.setHeaderEncoding("utf-8");
    (2)解决普通表单项的中文乱码问题:
    item.getString(“utf-8“);

    3.完善上传文件到指定目录:

    • 限制上传文件的大小:

    方式1:upload.setSizeMax(1024); 推荐使用
    方式2:long size = item.getSize();不推荐使用

    • 限制上传文件的类型:

    String fileName = item.getName();//.jpg JPG adf.ad.jpg adfad.gif
    String extName = fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();

    • 为了避免同名文件的覆盖,文件重命名:

    long newFileName= UUID.randomUUID();
    fileName = newFileName+"."+extName;

    4.下载文件:

    • 需求:

    将服务器的图片在客户端下载。

    • 关键代码:

    //创建输入流和输出流
    String photoName= stu.getPhotoName();
    String realPath = this.getServletContext().getRealPath("/upload");
    //InputStream is = new FileInputStream(“D:/Java/apache-tomcat-
    //7.0.69/webapps/updownload0/upload/"+photoName);
    InputStream is = newFileInputStream(realPath+"/"+photoName);
    OutputStream os = response.getOutputStream();//发送到客户端
    //使用输入流和输出流完成文件传递

    IOUtils.copy(is, os);
    //关闭输入流和输出流
    is.close();
    os.close();

    • 代码示例:
    package com.bjsxt.servlet;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URLEncoder;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.io.IOUtils;
    
    import com.bjsxt.entity.Students;
    import com.bjsxt.service.StudentService;
    import com.bjsxt.service.impl.StudentServiceImpl;
    
    public class DownServlet extends HttpServlet {
    
        public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            // 获取ID
            int id = Integer.parseInt(request.getParameter("id"));
            // 调用业务层查询该学生的所有信息
            StudentService service = new StudentServiceImpl();
            Students stu = service.findById(id);
    
            // 通过io流实现照片的下载(服务端到客户端)
            // 创建一个输入流和输出流
            String realPath = this.getServletContext().getRealPath("/upload");
            String fileName = realPath + "/" + stu.getPhotoName();
            File file = new File(fileName);
    
            response.setContentLength((int) file.length());// 文件长度
            response.setContentType(stu.getPhotoType());// mime类型
            
            String realName = stu.getRealName();// 文件的原名
            System.out.println(realName);
            String userAgent = request.getHeader("User-Agent").toLowerCase();
            
            //判断浏览器
            if (userAgent.indexOf("msie") >= 0) {
                realName = URLEncoder.encode(realName, "utf-8");
            } else {
                realName = new String(realName.getBytes("utf-8"),"iso-8859-1");
            }
    
            response.setHeader("Content-disposition", "attachment;filename=" + realName);
            InputStream is = new FileInputStream(file);// 读取服务端一个文件
            OutputStream os = response.getOutputStream();// 写入客户端
            System.out.println(realName);
            // 使用输入流和输出流完成复制操作
            IOUtils.copy(is, os);
            // 关闭流
            is.close();
            os.close();
    
            // get表单提交的中文乱码解决
            // request.setCharacterEncoding("utf-8");//post
    //       String name = request.getParameter("name");
            // byte [] bytes = name.getBytes("iso-8859-1");
            // name = new String(bytes,"utf-8");
    //       name = new String(name.getBytes("iso-8859-1"),"utf-8");
        }
    
    }
    
    • 视图层:jsp代码
    <td>
                        <a href="upload/${stu.photoName }">下载</a>
                        <a href="downServlet?id=${stu.id }">下载1</a>
    </td>
    

    相关文章

      网友评论

          本文标题:JavaEE学习day-58:分页技术和文件上传下载

          本文链接:https://www.haomeiwen.com/subject/toecmctx.html