Servlet处理文件上传(用Servlet实现注册登录的小例子)

不知道大家有没有这个感受,我们学习一门技术,光看不写是忘的很快的,特别是看完之后一段时间没有用到,很快就忘的差不多了。原因就是记忆不够深刻,好记性不如烂笔头,在自学过程中,学完之后一定要多练,这样才会记忆的更加深刻。也能提升我们写代码的感觉。

下面,我们来结合之前的学到的知识写一个简单的注册,登录的功能。
顺便学一下如何用Servlet上传文件

例子很简单·:
我们通过注册表单填写一些数据,提交给Servlet,Servlet拿出提交的数据保存到ServletContext中。
登录的时候拿到登录表单填写的数据,跟保存的用户数据进行比较,用户名和密码正确即为登录成功,跳转到个人信息页面即可。

开始吧!


注册页面 (register.jsp)

先来看看注册页面的表单代码,
如果表单涉及到文件上传,就要注意一下两点
1.enctype要设置为multipart/form-data,默认为application/x-www-form-urlencoded
2.提交方式要设置为post, 因为get有大小限制

来看代码

<%--
  Created by IntelliJ IDEA.
  User: yzq
  Date: 2018/7/25
  Time: 15:29
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册</title>
</head>
<body>


<%
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + application.getContextPath();

%>


<%--如果表单涉及到文件上传
1.enctype要设置为multipart/form-data  默认为application/x-www-form-urlencoded
2.提交方式要设置为post,get有大小限制
--%>
<form action="<%=basePath%>/register.do" method="post" enctype="multipart/form-data">


    账号:<input type="text" name="account"><br>
    密码:<input type="password" name="pwd"> <br>
    头像:<input type="file" name="img"><br>
    性别:<input type="radio" name="gender" value="男">男
    <input type="radio" name="gender" value="女">女

    <br>
    爱好:<input type="checkbox" name="hobbies" value="唱歌"> 唱歌
    <input type="checkbox" name="hobbies" value="看电影"> 看电影
    <input type="checkbox" name="hobbies" value="玩游戏"> 玩游戏
    <input type="checkbox" name="hobbies" value="敲代码"> 敲代码

    <br>

    <input type="submit" value="注册">

</form>

</body>
</html>


长这样,这里就不美化了,主要是实现逻辑

这里写图片描述


实体类(UserBean)
界面有了,下面我们来建一个UserBean,用来封装提交的用户数据
这里我们导入了Gson.jar用来处理json,后面会用到。

可以从gson maven仓库下载 jar包

package data;

public class UserBean {

    private String userName;
    private String account;
    private String img;
    private String gender;
    private String hobbies;


    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getHobbies() {
        return hobbies;
    }

    public void setHobbies(String hobbies) {
        this.hobbies = hobbies;
    }


    @Override
    public String toString() {
        return "UserBean{" +
                "userName='" + userName + '\'' +
                ", account='" + account + '\'' +
                ", img='" + img + '\'' +
                ", gender='" + gender + '\'' +
                ", hobbies='" + hobbies + '\'' +
                '}';
    }
}

初始化数据 (InitServlet)

实体类也有了,由于我们没有数据库,那我们就先一个创建个集合来存储注册产生的UserBean。这个集合要放到ServletContext作用域中,以便我们在其他地方获取。

我们可以创建一个Servlet在Tomcat启动时就进行初始化,并新建一个List用于存储User

注意配置下loadOnStartup 确保服务器已启动就初始化

package servlet;

import data.UserBean;

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.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet(name = "InitServlet",loadOnStartup = 0,value = "/initList")
public class InitServlet extends HttpServlet {

    @Override
    public void init() throws ServletException {
        super.init();


        System.out.println("InitServlet init");

        /*创建一个集合  保存注册的用户信息*/

        List<UserBean> userBeanList=new ArrayList<>();

        getServletContext().setAttribute("users",userBeanList);

    }
}

处理注册逻辑(RegisterServlet)

由于提交的数据需要处理上传的文件,那么我们就不能直接用之前的request.getParameter(“account”);的方式获取数据。
这里我们使用Apache提供的commons-fileupload这个jar包来处理文件上传,跟gson一样,下载commons-fileuploadcommons-io 后导入到项目即可。

下面我们来看看代码,注释写的很清楚了

package servlet;

import com.google.gson.Gson;
import data.UserBean;
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.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@WebServlet(name = "RegisterServlet", value = "/register.do")
public class RegisterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");


        /*判断request 的请求方式是否为post并且contentType是否以multipart/开头
         *
         * 如果不是说明是普通的表单提交
         * */
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;
        }

        /*创建一个DiskFileItemFactory对象,这里我们使用默认配置*/
        DiskFileItemFactory factory = new DiskFileItemFactory();
        /*创建一个ServletFileUpload对象*/
        ServletFileUpload servletFileUpload = new ServletFileUpload(factory);

        try {

            /*解析request对象,返回FileItem集合*/
            List<FileItem> items = servletFileUpload.parseRequest(request);

            /*创建一个UserBean  用于封装用户数据*/
            UserBean userBean = new UserBean();

            /*该集合用于存储提交的爱好数据*/
            List<String> hobbyList = new ArrayList<>();


            /*遍历FileItem集合*/
            for (FileItem item : items) {

                String filedName = item.getFieldName();//获取name属性

                System.out.println("filedName=" + filedName);

                if (item.isFormField()) {
                    /*处理表单项*/
                    String value = item.getString("utf-8");

                    System.out.println("value=" + value);

                    if (filedName.equals("account")) {
                        userBean.setAccount(value);
                    } else if (filedName.equals("pwd")) {
                        userBean.setPwd(value);
                    } else if (filedName.equals("gender")) {
                        userBean.setGender(value);
                    } else if (filedName.equals("hobbies")) {
                        hobbyList.add(value);
                    }

                } else {
                    /*处理文件上传*/

                    if (filedName.equals("img")) {
                        /*获取上传文件的名字*/
                        String fileName = item.getName();
                        System.out.println("上传的文件名称为:" + fileName);
                        
                        /*获取后缀名*/
                        int index = fileName.lastIndexOf(".");
                        String endWith = fileName.substring(index);
                        System.out.println("后缀名:" + endWith);
                        /*重新命名*/
                        String newFimeName = System.currentTimeMillis() + endWith;
                        System.out.println("新文件名称:" + newFimeName);

                        String path = getServletContext().getRealPath("./") + File.separator + "upload";


                        /*保存文件*/
                        File dir = new File(path);
                        if (!dir.exists()) {
                            System.out.println("文件夹不存在  创建");
                            dir.mkdir();
                        }
                        String filePath = path + File.separator + newFimeName;
                        File file = new File(filePath);
                        item.write(file);
                        userBean.setImg(filePath);

                    }

                }

            }

            userBean.setHobbies(hobbyList);
            System.out.println("注册完成" + userBean.toString());

            /*保存注册的数据*/
            List<UserBean> userList = (List<UserBean>) getServletContext().getAttribute("userList");
            userList.add(userBean);
            /*返回注册信息*/
            response.setCharacterEncoding("utf-8");

            response.getWriter().append("<h1>");
            response.getWriter().append("注册成功:" + new Gson().toJson(userBean));
            response.getWriter().append("</h1>");

            System.out.println("目前注册的用户个数:" + userList.size());


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


    }
}

我们先启动Tomcat来看看注册的效果

这里写图片描述

看看控制台的打印结果

这里写图片描述

再看看保存的图片

这里写图片描述

这样一来注册的逻辑基本完成了,我们这里只是一个简单的示例,在实际开发中要注意数据的校验,以及代码封装。

处理登录逻辑(LoginServlet)

登录界面很简单,长这样,我就不贴代码了

这里写图片描述

当我们输入账号和密码后点击登录会进入LoginServlet去处理逻辑,在LoginServlet中拿到数据然后跟集合中的数据进行比较。
账号也密码都正确时,视为登录成功,并跳转到成功页面显示用户信息

看代码:

package servlet;

import data.UserBean;

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.IOException;
import java.util.List;

@WebServlet(name = "LoginServlet", urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        
        /*获取账号和密码*/
        String account = request.getParameter("account");
        String pwd = request.getParameter("pwd");
        
        List<UserBean> userList = (List<UserBean>) getServletContext().getAttribute("userList");
        UserBean user = null;
        /*遍历集合中的user*/
        for (UserBean userBean : userList) {
            if (userBean.getAccount().equals(account)) {
                user = userBean;
            }
        }

        /*没找到说明该账号未注册*/
        if (user == null) {
            response.getWriter().write("该账号未注册");
        } else {
            
            if (pwd.equals(user.getPwd())) {
                /*密码正确,登录成功,将数据存入session*/
                request.getSession().setAttribute("user", user);
                /*跳转到loginSuccess.jsp*/
                getServletContext().getRequestDispatcher("/loginSuccess.jsp").forward(request, response);
            }else {
                response.getWriter().write("账号或密码错误");
            }


        }

    }
}

登录成功页面(loginSuccess.jsp)

当在LoginServlet中验证的账号密码都正确时,跳转到该页面。
我们在该页面简单的显示一下用户的账号和头像,需要注意图片的路径问题。我们存图片的时候是磁盘的绝对路径,要转为项目相对路径才能正常访问到。

<%@ page import="data.UserBean" %>
<%--
  Created by IntelliJ IDEA.
  User: yzq
  Date: 2018/7/25
  Time: 15:39
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>

    <style>
        img {
            width: 300px;
            height: 300px;
            margin: auto;

        }

    </style>
</head>
<body>

<%

    /*获取session中的user*/
    UserBean user = (UserBean) request.getSession().getAttribute("user");

    /*注意这里我们拿到的是磁盘绝对路径,我们要转为相对路径*/
    String imgPath = user.getImg();

    int index = imgPath.lastIndexOf("\\");

    String relativePath = application.getContextPath() + "/upload" + imgPath.substring(index);

    System.out.println("相对路径:" + relativePath);
%>


<h1>登录成功,账号为:<%=user.getAccount()%>
</h1>

<img src="<%=relativePath%>">

</body>
</html>


ok,代码写完了,我们来看看整体效果

先注册账号并输入正确的账号和密码

这里写图片描述

输入不存在的账号或错误的密码

这里写图片描述

好了,一个简单的demo就完成了。

demo

也可以去码云,获取代码,后面的练习都会在这里更新

©️2020 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值