第76天学习打卡(JavaWeb SMBMS 用户管理实现 用户显示的Servlet 文件上传)

SMBMS

用户管理实现

4用户显示的Servlet

1.获取用户前端的数据(查询)

2.判断请求是否需要执行,看参数的值判断

3.为了实现分页,需要计算出当前页面和总页面,页面大小…

4.用户列表展示

5.返回前端

package com.kuang.servlet.user;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.kuang.pojo.Role;
import com.kuang.pojo.User;
import com.kuang.service.role.RoleServiceImpl;
import com.kuang.service.user.UserService;
import com.kuang.service.user.UserServiceImpl;
import com.kuang.util.Constants;
import com.kuang.util.PageSupport;
import com.mysql.cj.util.StringUtils;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//实现Servlet复用
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if(method.equals("savepwd")&&method!=null){
            this.updatePwd(req,resp);
        }else if (method.equals("pwdmodify")&&method!=null){
            this.pwdModify(req,resp);
        }else if (method.equals("query")&&method!=null){
            this.query(req, resp);

        }


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req, resp);
    }

    //重点  难点
    public void query(HttpServletRequest req, HttpServletResponse resp){
        //查询用户列表

        //从前端获取数据
        String queryUserName = req.getParameter("queryname");
        String temp = req.getParameter("queryUserRole");
        String pageIndex = req.getParameter("pageIndex");
        int queryUserRole = 0;

        //获取用户列表
        UserServiceImpl userService = new UserServiceImpl();
        List<User> userList = null;
        //第一次走这个请求,一定是第一页,页面大小固定
        int pageSize = 5;//可以把这些写到配置文件中,方便后期修改 一页显示5个
        int currentPageNo = 1;

        if (queryUserName == null){
            queryUserName = "";
        }if (temp!=null&& !temp.equals("")){
            queryUserRole = Integer.parseInt(temp);//给查询复制  0 1 2 3

        }
        if (pageIndex!=null){

                currentPageNo = Integer.parseInt(pageIndex);

        }
        //获取用户的总数(分页:上一页,下一页的情况)
        int totalCount = userService.getUserCount(queryUserName, queryUserRole);
        //总页数支持
        PageSupport pageSupport = new PageSupport();
        pageSupport.setCurrentPageNo(currentPageNo);
        pageSupport.setPageSize(pageSize);
        pageSupport.setTotalCount(totalCount);

     //   int totalPageCount = pageSupport.getTotalCount();//总共有几页
        int totalPageCount = ((int)(totalCount/pageSize)) + 1;

        //控制首页和尾页
        //如果页面要小于1了,就显示第一页的东西
        if (currentPageNo<1){
            currentPageNo = 1;
        }else if (currentPageNo>totalPageCount){
            //当前页面大于了最后一页
            currentPageNo = totalPageCount;

        }
        //获取用户列表展示
         userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
        req.setAttribute("userList",userList);

        RoleServiceImpl roleService = new RoleServiceImpl();
        List<Role> roleList = roleService.getRoleList();
        req.setAttribute("roleList",roleList);
        req.setAttribute("totalCount",totalCount);
        req.setAttribute("currentPageNo",currentPageNo);
        req.setAttribute("totalPageCount",totalPageCount);
        req.setAttribute("queryUserName",queryUserName);
        req.setAttribute("queryUserRole",queryUserRole);

        //返回前端
        try {
            req.getRequestDispatcher("userlist.jsp").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    //修改密码
    public void updatePwd(HttpServletRequest req, HttpServletResponse resp){
        //从Session里面拿ID
        Object o = req.getSession().getAttribute(Constants.USER_SESSION);
        String newpassword = req.getParameter("newpassword");
        String oldpassword = req.getParameter("oldpassword");
        System.out.println("UserServlet:"+newpassword);

        boolean flag = false;
        System.out.println(o!=null);
        System.out.println(StringUtils.isNullOrEmpty(newpassword));

        if (o!=null && newpassword!=null){
            UserService userService = new UserServiceImpl();
            boolean b = userService.updatePwd(((User) o).getId(), newpassword);
            if (flag){
                req.setAttribute("message","修改密码成功,请退出,使用新密码登录");
                //密码修改成功,移除当前Session
                req.getSession().removeAttribute(Constants.USER_SESSION);

            }else{
                req.setAttribute("message","密码修改失败");

            }
        }else{
            req.setAttribute("message","新密码有问题");

        }
        try {
            req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //验证旧密码,session中有用户的密码
    public void pwdModify(HttpServletRequest req, HttpServletResponse resp){
        //从Session里面拿ID
        Object o = req.getSession().getAttribute(Constants.USER_SESSION);
        String oldpassword = req.getParameter("oldpassword");

        //万能的map:结果集
        Map<String, String> resultMap = new HashMap<String,String>();
        if (o==null){
            //Session失效了,session过期了
            resultMap.put("result","sessionerror");

        }else if (StringUtils.isNullOrEmpty(oldpassword)){
            //输入的密码为空
            resultMap.put("result","error");

        }else{
            String userPassword = ((User) o).getUserPassword();//Session中用户的表
           if (oldpassword.equals(userPassword)){
               resultMap.put("result","true");
           }else {
               resultMap.put("result","false");
           }

        }

        try {
            resp.setContentType("application/json");
            PrintWriter writer = resp.getWriter();
            //JSONArray阿里巴巴的JSON工具类,转换格式
            /*
             resultMap = ["result","sessionerror","result","error"]
             Json格式 = {key:value}
             */
            writer.write(JSONArray.toJSONString(resultMap));
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

推荐的前端网站:Layui

2020版IDEA创建项目没有javaEE没有web选项的解决办法

1.正常创建Java项目

image-20210325143816443

image-20210325143956498

然后点击弹出来的Java EE下的 web applocation 就可以了。

文件上传

1 准备工作

对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的。

一般选择采用apache的开源工具common-fileupload这个文件上传组件

common.fileupload是依赖于common.io这个包的,所以还需要下载这个包

https://mvnrepository.com/artifact/commons-io/commons-io/2.8.0

https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.4

把jar包导入项目目录

方法1:

1.创建lib包

image-20210325151518734

2.把jar包复制进这个lib下

image-20210325151645059

image-20210325151725518

方法2:

image-20210325152055239

第五步选择你需要的文件下的lib目录

第六步:

image-20210325152404482

image-20210325152527069

2.使用类介绍

【文件上传的注意事项】

1.为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。

2.为防止文件覆盖的现象发生,要为上传的文件产生一个唯一的文件名

3.要限制上传文件的最大值。

4.可以限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

【需要用到的类详解】

servletFileUpload负责处理上传的文件数据,并将表单中每个输入封装成一个FileItem对象,在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象。所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象,通过ServletFileUpload对象的构造方法或setFileItem Factory()方法设置ServletUpload对象的fileItemFactory属性。

FileItem类:

在HTML页面input必须有name<input type="file"name=“filename”>

表单如果包含一个文件上传输入项的话,这个表单的enctype属性就必须设置为multipart/form-data

<form action="${pageContext.request.contextPath}/upload.do"enctype="multipart/form-data"method="post">
    上传用户:<input type="text"name="username"><br/>
    上传文件1:<input type="file"name="file1"><br/>
    上传文件2:<input type="file"name="file2"><br/>
    <input type="submit"value="提交">
</form>
    

浏览器表单的类型如果为multipart/form-data,在服务器端想获取数据就要通过流。

【常用方法介绍】

//isFormFiled方法用于判断FileItem类对象封装的数据是一个普通文本表单
//还是一个文件表单,如果是普通表单字段则返回true,否则返回false
boolean isFormField();

//getFieldName方法用于返回表单标签name属性的值
String getFiledName();
//getString方法用于将FileItem对象保存的数据流内容以一个字符串返回
String getName();

//getName方法用于获得文件上传字段中的文件名
String getName();

//以流的形式返回上传文件的数据内容
InputStream getInputStream();

//delete方法用来清空FileItem类对象中存放的主体内容
//如果主体内容保存在临时文件中,delete方法将删除该临时文件
void delete();

ServletFileUpload类

ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成为一个FileItem对象中,使用其parseRequest(HttpServletRequest)方法,可以将通过表单中每个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回。使用该方法处理上传文件简单易用。

package com.kuang.servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

public class FileServlet extends HttpServlet {
  @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      //判断上传的文件是普通表单还是带文件的表单
      if (!ServletFileUpload.isMultipartContent(request)){
          return;//终止方法运行,说明这是一个普通的表单,直接返回

      }
      try {
      //创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问上传的文件
      String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
      File uploadFile = new File(uploadPath);
      if (!uploadFile.exists()){
          uploadFile.mkdir();//创建这个目录

      }
      //缓存,临时文件
      //临时路径,假如文件超过了预期的大小,我们就把他放到这个临时文件中,过几天自动删除,或者提醒用户转存为永久
      String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
      File file= new File( tmpPath );
      if (!file.exists()){
          file.mkdir();//创建这个临时目录

      }
      //处理上传的文件,一般都需要通过流来获取,我们可以使用request.getInputStream(),原生态的文件上传流获取,十分麻烦
      //但是我们都建议使用Apache的文件上传组件来实现,它需要依赖于commons-io组件


      /*
      ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象
      在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象
      所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象
      通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServeltFileUpload对象的fileItemFactory属性
      */
      //1.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的
      DiskFileItemFactory factory = new DiskFileItemFactory();

     /* //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件中
      factory.setSizeThreshold(1024*1024);//缓冲区大小为1M
      factory.setRepository(file);//临时目录的保存目录,需要一个File*/

      //2.获取ServletFileUpload
      ServletFileUpload upload = new ServletFileUpload(factory);

   /*   //监听文件的上传进度:
      upload.setProgressListener(new ProgressListener() {
          @Override
          //pBytesRead:已经读取到的文件大小
          //pContentLength : 文件大小
          public void update(long pBytesRead, long pContentLength, int pItems) {
              System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead);

          }
      });
      //处理乱码问题
      upload.setHeaderEncoding("UTF-8");
      //设置单个文件的最大值
      upload.setFileSizeMax(1024*1024*10);
      //设置总共能够上传的文件的大小
      //1024 = 1kb * 1024 = 1M * 10 = 10M
      upload.setSizeMax(1024*1024*10);*/

      //3,处理上传文件
      //把前端请求解析,封装成一个FileItem对象,需要ServletFileUpload对象中获取
          List<FileItem> fileItems = upload.parseRequest(request);

          //fileItem 每一个表单对象
          for (FileItem fileItem : fileItems) {
              //判断上传的文件是普通的表单还是带文件的表单
              if (fileItem.isFormField()){
                  //getFiledName指的是前端表单控制件的name;
                  String name = fileItem.getFieldName();
                  String value = fileItem.getString("UTF-8");//处理乱码
                  System.out.println(name+":"+value);

              }else {
                  //文件

                  //=======处理文件======
                  //拿到文件名字
                  String uploadFileName = fileItem.getName();
                  //可能存在文件名不合法的情况
                  if (uploadFileName.trim().equals("")||uploadFileName==null){
                       continue;
                  }
                  //获得上传的文件名  /images/girl/paojie.png
                  String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                  //获得文件的后缀名
                  String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                  /*
                  如果文件后缀名fileExtName 不是我们所需要的
                  就直接return,不处理,告诉用户文件类型不对

                  */

                  //可以使用UUID(唯一识别的通用码),保证文件名唯一;
                  //UUID.randomUUID(),随机生成一个唯一识别的通用码

                  //网络传输中的东西,都需要序列化
                  //POJO,实体类,如果想要在多个电脑上运行,传输===》需要把对象都序列化了
                  //JNI = Java Native Interface
                  //implements Serializable : 标记接口, JVM ---> Java栈 本地方法栈  native---->C++
                  String uuidPath = UUID.randomUUID().toString();



                  //=======存放地址======
                  //存到哪?uploadPath
                  //文件真实存在的路径  realPath
                  String realpath = uploadPath + "/" + uuidPath;
                  //给每个文件都创造一个对应的文件夹
                  File realPathFile = new File(realpath);
                  if (!realPathFile.exists()){
                      realPathFile.mkdir();
                  }

                  //======文件传输========
                  //获取文件上传的流
                  InputStream inputStream = fileItem.getInputStream();

                  //创建一个文件输出流
                  //realPath = 真实的文件夹
                  //差了一个文件;加上输出文件的名字+"/"+uuidFileName
                  FileOutputStream fos = new FileOutputStream(realpath+"/"+fileName);

                  //创建一个缓冲区
                  byte[] buffer = new byte[1024*1024];

                  //判断是否读取完毕
                  int len = 0;
                  //如果大于0说明还存在数据
                  while ((len=inputStream.read(buffer))>0){
                      fos.write(buffer,0,len);
                  }
                  //关闭流
                  fos.close();
                  inputStream.close();
                  msg = "文件上传成功";
                  fileItem.delete();//上传成功,清除临时文件

              }

          }

      } catch (FileUploadException e) {
          e.printStackTrace();
      }


  }

 @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

完整代码:

package com.kuang.servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

public class FileServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        // response.getWriter().append("Served at: ").append(request.getContextPath());

        // 判断上传的文件普通表单还是带文件的表单
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;//终止方法运行,说明这是一个普通的表单,直接返回
        }
        //创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访间上传的文件;
        String uploadPath =this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()){
            uploadFile.mkdir(); //创建这个月录
        }

        // 创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问上传的文件
        String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
        File file = new File(tmpPath);
        if (!file.exists()) {
            file.mkdir();//创建临时目录
        }

        // 处理上传的文件,一般都需要通过流来获取,我们可以使用 request, getInputstream(),原生态的文件上传流获取,十分麻烦
        // 但是我们都建议使用 Apache的文件上传组件来实现, common-fileupload,它需要旅 commons-io组件;
        try {
            // 创建DiskFileItemFactory对象,处理文件路径或者大小限制
            DiskFileItemFactory factory = getDiskFileItemFactory(file);
            /*
             * //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件 factory.setSizeThreshold(1024 *
             * 1024); //缓存区大小为1M factory.setRepository (file);//临时目录的保存目录,需要一个File
             */

            // 2、获取ServletFileUpload
            ServletFileUpload upload = getServletFileUpload(factory);

            // 3、处理上传文件
            // 把前端请求解析,封装成FileItem对象,需要从ServletFileUpload对象中获取
            String msg = uploadParseRequest(upload, request, uploadPath);

            // Servlet请求转发消息
            System.out.println(msg);
            if(msg == "文件上传成功!") {
                // Servlet请求转发消息
                request.setAttribute("msg",msg);
                request.getRequestDispatcher("info.jsp").forward(request, response);
            }else {
                msg ="请上传文件";
                request.setAttribute("msg",msg);
                request.getRequestDispatcher("info.jsp").forward(request, response);
            }

        } catch (FileUploadException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }

    public static DiskFileItemFactory getDiskFileItemFactory(File file) {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件中;
        factory.setSizeThreshold(1024 * 1024);// 缓冲区大小为1M
        factory.setRepository(file);// 临时目录的保存目录,需要一个file
        return factory;
    }

    public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 监听长传进度
        upload.setProgressListener(new ProgressListener() {

            // pBYtesRead:已读取到的文件大小
            // pContextLength:文件大小
            public void update(long pBytesRead, long pContentLength, int pItems) {
                System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead);
            }
        });

        // 处理乱码问题
        upload.setHeaderEncoding("UTF-8");
        // 设置单个文件的最大值
        upload.setFileSizeMax(1024 * 1024 * 10);
        // 设置总共能够上传文件的大小
        // 1024 = 1kb * 1024 = 1M * 10 = 10м

        return upload;
    }

    public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath)
            throws FileUploadException, IOException {

        String msg = "";

        // 把前端请求解析,封装成FileItem对象
        List<FileItem> fileItems = upload.parseRequest(request);
        for (FileItem fileItem : fileItems) {
            if (fileItem.isFormField()) {// 判断上传的文件是普通的表单还是带文件的表单
                // getFieldName指的是前端表单控件的name;
                String name = fileItem.getFieldName();
                String value = fileItem.getString("UTF-8"); // 处理乱码
                System.out.println(name + ": " + value);
            } else {// 判断它是上传的文件

                // ============处理文件==============

                // 拿到文件名
                String uploadFileName = fileItem.getName();
                System.out.println("上传的文件名: " + uploadFileName);
                if (uploadFileName.trim().equals("") || uploadFileName == null) {
                    continue;
                }

                // 获得上传的文件名/images/girl/paojie.png
                String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                // 获得文件的后缀名
                String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);

                /*
                 * 如果文件后缀名fileExtName不是我们所需要的 就直按return.不处理,告诉用户文件类型不对。
                 */

                System.out.println("文件信息[件名: " + fileName + " ---文件类型" + fileExtName + "]");
                // 可以使用UID(唯一识别的通用码),保证文件名唯
                // 0UID. randomUUID(),随机生一个唯一识别的通用码;
                String uuidPath = UUID.randomUUID().toString();

                // ================处理文件完毕==============

                // 存到哪? uploadPath
                // 文件真实存在的路径realPath
                String realPath = uploadPath + "/" + uuidPath;
                // 给每个文件创建一个对应的文件夹
                File realPathFile = new File(realPath);
                if (!realPathFile.exists()) {
                    realPathFile.mkdir();
                }
                // ==============存放地址完毕==============


                // 获得文件上传的流
                InputStream inputStream = fileItem.getInputStream();
                // 创建一个文件输出流
                // realPath =真实的文件夹;
                // 差了一个文件;加上翰出文件的名产"/"+uuidFileName
                FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);

                // 创建一个缓冲区
                byte[] buffer = new byte[1024 * 1024];
                // 判断是否读取完毕
                int len = 0;
                // 如果大于0说明还存在数据;
                while ((len = inputStream.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                // 关闭流
                fos.close();
                inputStream.close();

                msg = "文件上传成功!";
                fileItem.delete(); // 上传成功,清除临时文件
                //=============文件传输完成=============
            }
        }
        return msg;

    }

}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值