Servlet入门及其基本用法(下载文件,上传文件,BaseServlet)

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。(百度百科)

目录

下载文件:

上传文件:

 BaseServlet功能:

请求转发与重定向


 


下载文件:

设置好response的相应头格式

response.setContentType("application/force-download");
response.setHeader("Content-Disposition","attachment;filename=\""+filename+"\"");

关于响应头格式csdn上有很多优秀博主有详细介绍: @大小鱼鱼鱼与鱼.

文件的读取位置没放对很头疼,我把文件放置在这个位置:

@WebServlet( "/downServlet")
public class DownServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        OutputStream out;
        InputStream in;
        ServletContext servletContext = getServletContext();
      

        String filename = request.getParameter("filename");//获取请求文件名
        if(filename==null){
            out= response.getOutputStream();
            out.write("Please input filename".getBytes("utf-8"));
            out.close();
            return;
        }
        in=servletContext.getResourceAsStream("/WEB-INF/img/" +filename);//这里文件的路径要注意写对
        //设置响应正文的MIME类型
        response.setContentType("application/force-download");
        response.setHeader("Content-Disposition","attachment;filename=\""+filename+"\"");

        out= response.getOutputStream();
        int len=0;
        byte[]bys=new byte[1024];
        while((len=in.read(bys))!=-1){
            out.write(bys,0,len);//将输入流写到页面上
        }
        in.close();
        out.close();

        in= ServletContext.class.getResourceAsStream("/img/"+filename);

    }


}

html页面很简陋

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>down</title>
</head>
<body>
  <a href="/downServlet?filename=1.jpg" onclick="">点击下载图片1</a> <br>
  <a href="/downServlet?filename=2.jpg" onclick="">点击下载图片2</a>
</body>
</html>

效果:

上传文件:

使用fileuploadjar包配合 IO jar包,里面有工厂类.

同样要上传文件位置也要写对,这里我直接用绝对路径能省点事.

    private String filePath="E:\\develop\\files\\store";//文件放置目录
    private String tempFilePath="E:\\develop\\files\\store";//临时目录
@WebServlet("/upload")
public class upload extends HttpServlet {
    private String filePath="E:\\develop\\files\\store";//文件放置目录
    private String tempFilePath="E:\\develop\\files\\store";//临时目录
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        System.out.println("被访问了...");//测试
        response.setContentType("text/plain");
        response.setCharacterEncoding("utf-8");
        PrintWriter outNet = response.getWriter();
        try {
            //创建一个基于硬盘的fileitem工厂
            DiskFileItemFactory factory=new DiskFileItemFactory();
            //设置想硬盘写数据时所用的缓冲区的大小 此处4M
            factory.setSizeThreshold(4*1024*1024);
            //设置临时目录
            factory.setRepository(new File(tempFilePath));

            //创建一个文件上传处理器
            ServletFileUpload upload=new ServletFileUpload(factory);
            //设置允许上传的文件的最大尺寸 此处4M
            upload.setSizeMax(4*1024*1024);
            List Items=null;
            //解析request对象的复合表单数据 返回一个fileItem对象的List集合
            request.setCharacterEncoding("utf-8");
            Items = upload.parseRequest(request);
            Iterator iter=Items.iterator();
            while(iter.hasNext()){
                //遍历该集合 拿到数据
                FileItem item=(FileItem) iter.next();
                if(item.isFormField()){
                    //处理普通的表单域
                    processFormField(item,outNet);
                }
                else {
                    //处理上传文件
                    processUploadFile(item,outNet);
                }
            }
            outNet.close();
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void processFormField(FileItem item, PrintWriter outNet) {
        String name = item.getFieldName();//获取表单域的名字
        String string = item.getString();//获取表单域
        outNet.println(name+":"+string+"\r\n");
    }
    private void processUploadFile(FileItem item, PrintWriter outNet) throws Exception {
        String Filename = item.getName();//获取包括路径在内的文件名字
        int index = Filename.lastIndexOf("\\");
        Filename=Filename.substring(index+1,Filename.length());//分割得到文件名
        long size = item.getSize();

        if(Filename.equals("")&&size==0)return;//不存在就直接return
        File uploadFile=new File(filePath+"/"+Filename);//创建一个新文件
        item.write(uploadFile);//写入新文件

        outNet.println(Filename+"is saved");
        outNet.println("The size of "+Filename+" is "+size/1000+" kb\r\n");
    }


}

html页面也是写得比较简陋,只为实现功能

注意请求头格式:enctype="multipart/form-data"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>upload</title>
</head>
<body>
    <form name="uploadForm" method="post"
        enctype="multipart/form-data" action="upload">
        <table>
            <tr>
                <td><div align="right">User Name:</div></td>
                <td><input type="text" name="username" size="30"></td>
            </tr>
            <tr>
                <td><div align="right">Upload File1:</div></td>
                <td><input type="file" name="file1" size="30"></td>
            </tr>
            <tr>
                <td><div align="right">Upload File2:</div></td>
                <td><input type="file" name="file2" size="30"></td>
            </tr>
            <tr>
                <td><input type="submit" name="submit" value="upload"></td>
                <td><input type="reset" name="reset" value="reset"></td>
            </tr>
        </table>
    </form>
</body>
</html>

效果:

看看效果:可以看到上传成功了.

硬盘目录也出现这两个上传的文件了:

 BaseServlet功能:

减少Servlet的数量,现在是一个功能一个Servlet,将其优化为一个模块一个Servlet,相当于在数据库中一张表对应一个Servlet,在Servlet中提供不同的方法,完成用户的请求。也就是说写一个Servlet就够了,其他的servlet写成方法就可以直接访问.原理是反射-->反射的基本使用

关于BaseServlet详细介绍:@阿顾同学

public class BaseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String requestURI = req.getRequestURI();//获取请求的路径
//        System.out.println(requestURI);//   /userServlet/add
        //获取方法名
        String methodName = requestURI.substring(requestURI.lastIndexOf('/') + 1);
//        System.out.println(methodName);  //add
//        System.out.println(this);//web.servlet.UserServlet@38e182e5
        //可以看到这里的this是从URL过来的对象而不是这个baseServlet
        try {
            //通过反射获取方法
            Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this,req,resp);//这里的this是访问它的那个方法

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}

下面的cookie测试servlet 和请求转发/重定向就是用了BaseServlet.

是在客户端访问web组件时,服务器响应给客户端,给客户端硬盘上存放的信息.


Cookie类。
Response.addCookie

@WebServlet( "/test/*")
public class UserServlet extends BaseServlet {
    private int count=0;

    public void cookieTest(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //测试cookie
        response.setContentType("text/plain");
        //获取http请求中所有的cookie
        Cookie[] cookies = request.getCookies();
        if(cookies!=null){
            //访问每个cookie
            for(int i=0;i<cookies.length;i++){
                //向页面输出cookie信息
                response.getWriter().println("Cookie name :"+cookies[i].getName());//向页面输出cookie名
                response.getWriter().println("Cookie values :"+cookies[i].getValue());//向页面输出cookie值
                response.getWriter().println("Cookie MAX age :"+cookies[i].getMaxAge()+"\r\n");//向页面输出cookie有效期
            }
        }else {
            response.getWriter().println("No Cookies!");
        }
        //向客户端写入cookie
        response.addCookie(new Cookie("cookieName"+count,"cookieValue"+count));
        count++;
    }
}

第一遍访问,没有cookie 


后面几次就有了。

请求转发与重定向

简单的说,两者的功能都是实现从源web组件跳转到目标web组件。

request的请求转发,源组件和目标组件处理的是同个客户请求,他们共享同个request和response。


Response的重定向,是在httpServletResponse接口中定义的,由http协议规定的。源组件和目标组件不共享request,所以不共享数据。源组件要是有生成响应结果,客户端不会接受到,用了重定向,客户端接收的将是目标组件的响应结果。
二者的使用条件是,需要共享数据时用请求转发,否则使用重定向。

请求转发测试:

public void requestTest1(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        //源组件
        String msg="This a msg from requestTest1";
        request.setAttribute("msg",msg);//存储信息
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/test/requestTest2");//写上目标地址,请求分发器实现转发
        requestDispatcher.forward(request,response);//将这两个发送过去

        //不应该在源组件这里提交相应结果,这里的响应结果不会被发送到客户端
        response.getWriter().println(msg+"  now is: test1");
    }
    public void requestTest2(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        //目标组件
        String msg = (String) request.getAttribute("msg");//从源组件得到该信息
        response.getWriter().println(msg+"  now is: test2");
    }

看看结果:

 

 重定向测试:

public void responseTest1(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        //源组件
        String msg="This a msg from responseTest1";
        request.setAttribute("msg",msg);//存储信息
        response.sendRedirect("test/responseTest2");//重定向过去

    }
    public void responseTest2(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        //目标组件
        String msg = (String) request.getAttribute("msg");//从源组件得到该信息
        System.out.println("重定向能否收到信息?"+msg);

        response.getWriter().println("I am in responseTest2 now");
    }

 看看结果:

 可以看到,重定向的目标组件并没有收到源组件的信息

可以看到成功转发到目标组件这边.

不知不觉就写了两天...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值