美文网首页
Java - Part 12

Java - Part 12

作者: 低调的灬攻城狮 | 来源:发表于2020-02-26 00:50 被阅读0次

    一、文件上传

    1、文件上传三要素

    • 提供form表单,method必须是post
    • form表单的enctype必须是multipart/form-data
    • 提供input type="file" 类型文件上传

    2、文件上传需要导入的包
    实现文件上传要导入的两个包是file-ipload与commons-io

    3、文件上传的servlet

    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    import java.util.UUID;
    
    @WebServlet("/upload")
    public class UploadServlet2 extends HttpServlet {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置参数
            DiskFileItemFactory factory = new DiskFileItemFactory();
            try {
                //创建解析器
                ServletFileUpload upload = new ServletFileUpload(factory);
                upload.setHeaderEncoding("utf-8"); //设置编码格式
                //解析上传的内容
                List<FileItem> fileItems = upload.parseRequest(req);
                for (FileItem fileItem : fileItems) {
                    // fileItem.getFieldName() :input的name值
                    //fileItem.getName() : 获取文件名
                    //组装新文件名
                    String oldName = fileItem.getName();
                    String newName = UUID.randomUUID().toString()+System.currentTimeMillis()+oldName.substring(oldName.lastIndexOf("."));
                    FileOutputStream fos =new FileOutputStream("d:\\ceshi\\"+newName);
                    InputStream is = fileItem.getInputStream();
                    byte[] bs = new byte[8192];
                    int len;
                    while ((len = is.read(bs)) != -1) {
                        fos.write(bs,0,len);
                    }
                    fos.close();
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
        }
    }
    

    4、文件上传的注意问题

    • 上传文件应该放在外界无法直接访问的目录下,比如位于WEB-INF目录下
    • 为了防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
    • 为了防止一个目录下面出现太多文件,要使用hash算法打散存储
    • 要限制上传文件的最大值
    • 要限制上传文件的类型

    二、文件下载

    实现文件下载的时候最重要的是要编写一个Servlet让浏览器不去解析文件而直接下载

    import org.apache.tomcat.util.http.fileupload.FileItem;
    import org.apache.tomcat.util.http.fileupload.FileUploadException;
    import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
    import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
    import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.net.URLEncoder;
    import java.util.List;
    import java.util.UUID;
    
    @WebServlet("/download")
    public class DownloadServlet extends HttpServlet {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //重新设置了发送给浏览器的图片名与编码
            resp.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode("图片.jpg","utf-8"));
            FileInputStream fis = new FileInputStream("d:\\timg.jpg");
            OutputStream os = resp.getOutputStream();
            //小数组读写
            byte[] bs = new byte[8192];
            int len;
            while ((len = fis.read(bs)) != -1) {
                os.write(bs,0,len);
            }
            //只有真正是自己创建的流对象才需要关闭,
            fis.close();
        }
    }
    

    三、全局压缩

    实现全局压缩要用到过滤器,最重要的是将自己组装的response伪装传给其他的Servlet,让servlet的返回数据写进我们提供的response中,然后自己再压缩返回给浏览器

    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpServletResponseWrapper;
    import java.io.*;
    import java.util.zip.GZIPOutputStream;
    
    @WebFilter("/*")
    public class GzipFilter implements Filter {
        public void init(FilterConfig filterConfig) throws ServletException { }
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            //先找一个容器用来存储用户将要写回到浏览器的数据
                // 给用户一个假的HttpServletResponse , 里面的流也是假的(我们自己造的存储空间)
            //压缩
            //告诉浏览器这时压缩之后的数据
            //将数据写回到浏览器
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            //想要压缩返回的内容,就必须要拦截输出流
            MyResponse resp = new MyResponse(response);
            filterChain.doFilter(servletRequest,resp);//放行
            //获取所有返回的数据
            byte[] bs = resp.getBytes();
            //创建一个内存流, 用来存放压缩之后的数据
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            GZIPOutputStream gzip = new GZIPOutputStream(baos);
            gzip.write(bs);
            gzip.close();
            bs = baos.toByteArray(); //获取到压缩之后的数据
            //真正写回数据之前, 要告诉浏览器压缩格式, 让浏览器解压缩
            response.setHeader("Content-Encoding","gzip");
            //调用真正的数据流,将压缩之后的数据写回到浏览器
            servletResponse.getOutputStream().write(bs);
        }
        public void destroy() { }
        public class MyResponse extends HttpServletResponseWrapper{
            private ByteArrayOutputStream baos = new ByteArrayOutputStream();
            private PrintWriter pw = null;
            private MyOutputStream ms = null;
            public MyResponse(HttpServletResponse response) {
                super(response);
            }
            public ServletOutputStream getOutputStream() throws IOException {
                if(ms==null){
                    ms = new MyOutputStream(baos);
                }
                return ms;
            }
            public PrintWriter getWriter() throws IOException {
                //当servlet调用getWriter获取字符流准备写出内容时,获取到的是一个假的输出流
                //写出的内容都会放到内存流中
                if(pw==null){
                    pw = new PrintWriter(baos);
                }
                return pw;
            }
            public byte[] getBytes() {
                if(pw!=null){
                    pw.flush();
                }
                return baos.toByteArray();
            }
        }
        public class MyOutputStream extends ServletOutputStream {
            private ByteArrayOutputStream baos;
            public MyOutputStream(ByteArrayOutputStream baos){
                this.baos = baos;
            }
            public boolean isReady() {
                return false;
            }
            public void setWriteListener(WriteListener writeListener) { }
            public void write(int b) throws IOException {
                baos.write(b);
            }
        }
    }
    

    四、jQuery

    jQuery是一个JavaScript函数库,提供了更为简洁的操作
    1、安装

    • 官网下载:
    • 百度CDN
    • 新浪CDN
    • Google CDN
    • Microsoft CDN

    2、jQuery语法
    $(selector).action(parameter):selector是选择器,action是事件,如果没有参数paramter是执行这个事件,如果有参数parameter是执行该事件的时候应该执行的函数

    • 2.1 jQuery选择器

    • 元素选择器:$("p")

    • id选择器:$("#test")

    • 类选择器:$(".test")

    • 2.2 常见事件

    鼠标事件 键盘事件 表单事件 文档/窗口事件
    click keypress submit load
    dblclick keydown change resize
    mouseenter keyup focus scroll
    mouseleave blur unload

    3、jQuery效果

    • 3.1 显示隐藏
      • hide():隐藏元素
      • show():显示元素
      • toggle():切换显示与隐藏
    • 3.2 淡入淡出
      • fadeIn():淡入
      • fadeOut():淡出
      • fadeToggle():切换淡入与淡出
    • 3.3 滑动
      • slideDown():向下滑动
      • slideUp():向上滑动
      • slideToggle():切换
    • 3.4 动画
      • animate()

    4、jQuery HTML

    • 4.1 捕获与设置

      • text() - 设置或返回所选元素的文本内容
      • html() - 设置或返回所选元素的内容(包括 HTML 标记)
      • val() - 设置或返回表单字段的值
        上面的三个方法,如果括号中有参数就是设置,没有参数就是获取
      • attr("color","red"):设置属性
    • 4.2 添加元素

      • append() - 在被选元素的结尾插入内容
      • prepend() - 在被选元素的开头插入内容
      • after() - 在被选元素之后插入内容
      • before() - 在被选元素之前插入内容
    • 4.3 删除元素

      • remove() - 删除被选元素(及其子元素)
      • empty() - 从被选元素中删除子元素
    • 4.4 CSS类

      • addClass() - 向被选元素添加一个或多个类
      • removeClass() - 从被选元素删除一个或多个类
      • toggleClass() - 对被选元素进行添加/删除类的切换操作
      • css() - 设置或返回样式属性
    • 4.5 CSS方法

      • css()

    5、jQuery遍历

    • parent()
    • parents()
    • parentsUntil()
    • children():返回被选元素的所有直接子元素
    • find():所有后代元素
    • siblings():所有同胞元素
    • next():下一个同胞元素

    6、AJAX
    异步JavaScript和XML,在不加载整个网页的情况下。AJAX通过后台加载数据,并在网页上进行显示

    • $.ajax()
    • $.get()
    • $.post()

    五、MVC和三层模型

    1、三层模型

    • web:编写servlet,处理前台发送来的数据
    • service:位于web层与Dao层之间,处理业务逻辑
    • dao:用于和数据库交互

    2、MVC模型

    • M:model:模型模块,存储与操作的数据。对应于数据库,JavaBean。
    • V:view:视图模块。系统应该具备和用户交流的能力。jsp,html。
    • C:control:控制模块,控制视图和数据的连接。三层模型是对该层的细分。

    3、异步检测用户名是否可用
    解决这个问题的思路是在前台页面使用Ajax接收用户输入的用户名,然后发送到后台进行检测,返回特定的信息代表是否可用,然后Ajax中根据特定的信息回显告诉用户是否可用。

    $.ajax({
            //将要请求的servlet
            url:"/user/register",
            type:"post",
            data:{userName:userName,password:password},
            //返回的数据格式
            dataType:"json",
            success: function (data) {
                //根据返回的code进行不同的操作
                if(data.code==-1){
                    $("#message").text(data.message);
                }else{
                    $("#message").text(data.message+",立即为您跳转页面");
                    setTimeout(function () {
                        location.href="/resource/pages/login.jsp";
                    },2000)
                }
            }
        })
    
    @WebServlet("/user/register")
    public class Resgiter extends HttpServlet {
        private UserService userService = new UserService();
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            UserBean user = WebUtils.populate(UserBean.class,req);
            //message是我们自己定义的一个类,里面有三个成员变量:code、message与data
            //用于给Ajax返回数据,Ajax拿到数据之后进行判断用户名是否可用
            ResponseMessage message = new ResponseMessage();
    
            if(user.getUserName()==null||"".equals(user.getUserName().trim())){
                message.setCode(-1);
                message.setMessage("对不起,用户名不能为空");
                WebUtils.writeOut(resp,message);
                return;
            }
            //这个方法是用来检查用户名是否可用,返回的是boolean值
            boolean flg = userService.checkUserName(user.getUserName());
            if(!flg){
                message.setCode(-1);
                message.setMessage("对不起,用户名已经存在");
                WebUtils.writeOut(resp,message);
                return;
            }
            if(user.getPassword()==null||"".equals(user.getPassword().trim())){
                message.setCode(-1);
                message.setMessage("对不起,密码不能为空");
                WebUtils.writeOut(resp,message);
                return;
            }
            if(!user.getPassword().equals(user.getRepassword())){
                message.setCode(-1);
                message.setMessage("对不起,两次密码不一致");
                WebUtils.writeOut(resp,message);
                return;
            }
            //这个方法用来保存 用户
            flg = userService.saveUser(user);
            if(flg){
                message.setCode(1);
                message.setMessage("恭喜您,注册成功");
                WebUtils.writeOut(resp,message);
            }else{
                message.setCode(-1);
                message.setMessage("对不起,用户名已经存在");
                WebUtils.writeOut(resp,message);
            }
        }
    }
    

    4、Ajax上传图片

        function chooseImg(){
            $("#icon").click();
        }
        function upload(){
            //创建一个FormData对象用来存放文件
            var fromData = new FormData();
            var img = $("#icon")[0].files[0];
            fromData.append("file",img);
            $.ajax({
                url:"/file/upload",
                type:"post",
                data:fromData,
                contentType:false, //控制拼接格式
                processData:false, //控制转字符串
                cache:false,
                dataType:"json",
                success:function (data) {
                    if(data.code==1){
                        $("#img").attr("src","/file/getImg?fileName="+data.data[0])
                    }else{
                        alert("对不起上传失败");
                    }
                }
            })
    
    @WebServlet("/file/upload")
    public class Upload extends HttpServlet {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ResponseMessage message = new ResponseMessage();
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
            List<String> names = new ArrayList<>();
            try {
                //通过解析器解析req,返回的是一个List,每一个FileItem是一个文件
                List<FileItem> items = servletFileUpload.parseRequest(req);
                for (FileItem item : items) {
                    String oldName = item.getName();
                    //生成新的唯一的文件名
                    String newName = UUID.randomUUID().toString()+System.currentTimeMillis();
                    newName+= oldName.substring(oldName.lastIndexOf("."));
                    //根据新的文件名在文件服务器上创建一个新文件
                    FileOutputStream fos = new FileOutputStream("d:\\ceshi\\"+newName);
                    InputStream is = item.getInputStream();
                    byte[] bs = new byte[8192];
                    int len;
                    while ((len = is.read(bs)) != -1) {
                        fos.write(bs, 0, len);
                    }
                    fos.close();
                    names.add(newName);
                }
                message.setCode(1);
                message.setMessage("上传完毕");
                //将新的文件名的集合返回去
                message.setData(names);
                WebUtils.writeOut(resp,message);
                return;
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
            //如果上传文件出现了异常
            message.setCode(-1);
            message.setMessage("上传失败");
            WebUtils.writeOut(resp,message);
        }
    }
    

    相关文章

      网友评论

          本文标题:Java - Part 12

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