JavaWeb基础学习笔记之Servlet3.0

1.Servlet3.0

在Servlet3.0中可以使用注解代替使用配置文件注册servlet的模式
内嵌文件上传功能

2.Servlet注解的使用

    创建servlet
        在类上面添加 @WebServlet(urlPatterns={ "/demo1", "/demo2" },loadOnStartup=1)

    创建listener
        在类上添加 @WebListener

    创建filter
        在类上添加 @WebFilter(urlPatterns="/*")  

例子
Servlet

//使用注解
@WebServlet(urlPatterns= {"/demo1"})
public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Hello World");
    }
}

Filter

//使用注解注册过滤器
//urlPatterns配置过滤的路径
@WebFilter(urlPatterns="/*")
public class TestFilter implements Filter{
    public void destroy() {

    }
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
            throws IOException, ServletException {
        System.out.println("Filter...");
        arg2.doFilter(arg0, arg1);
    }
    public void init(FilterConfig arg0) throws ServletException {

    }
}

Listener

@WebListener
public class TestListener implements ServletContextListener{
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("Listener Destroyed...");
    }
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("Listener Initialize...");
    }
}

结果:

四月 14, 2018 9:22:28 下午 org.apache.jasper.servlet.TldScanner scanJars
信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.


Listener Initialize...


四月 14, 2018 9:22:28 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory [D:\Program Files\Tomcat 8.5\webapps\docs]
四月 14, 2018 9:22:30 下午 org.apache.jasper.servlet.TldScanner scanJars
信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
四月 14, 2018 9:22:30 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deployment of web application directory [D:\Program Files\Tomcat 8.5\webapps\docs] has finished in [2,209] ms
四月 14, 2018 9:22:30 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory [D:\Program Files\Tomcat 8.5\webapps\manager]
四月 14, 2018 9:22:32 下午 org.apache.jasper.servlet.TldScanner scanJars
信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
四月 14, 2018 9:22:32 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deployment of web application directory [D:\Program Files\Tomcat 8.5\webapps\manager] has finished in [2,032] ms
四月 14, 2018 9:22:32 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory [D:\Program Files\Tomcat 8.5\webapps\ROOT]
四月 14, 2018 9:22:34 下午 org.apache.jasper.servlet.TldScanner scanJars
信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
四月 14, 2018 9:22:34 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deployment of web application directory [D:\Program Files\Tomcat 8.5\webapps\ROOT] has finished in [2,108] ms
四月 14, 2018 9:22:34 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-nio-8080"]
四月 14, 2018 9:22:34 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-nio-8009"]
四月 14, 2018 9:22:34 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 11015 ms


Filter...
Hello World

3.文件上传

1.浏览器端的要求:

    表单的提交方法必须是post

    必须有一个文件上传组件  <input type="file" name=""/>

    必须设置表单的enctype=multipart/form-data

2.服务器端的要求:

    servlet3.0中
        需要在servlet中添加注解
            @MultipartConfig

        接受普通上传组件 (除了文件上传组件):request.getParameter(name属性的值)

        接受文件上传组件 request.getPart(name属性的值);
            getName():获取的name的属性值

        获取文件名:
             part.getHeader("Content-Disposition"):获取头信息 然后截取

3.上传注意的问题:

    名字重复 随机名称
        在数据库中提供两个字段,
            一个字段用来存放文件的真实名称  1.jpg
            另一个字段用来存放文件存放路径  g:/sdfasdf.jpg

        随机名称:
            uuid
            时间戳
    文件安全
        重要的文件存放在 web-inf 或者 meta-inf 或者 服务器创建一个路径
        不是很重要的文件 项目下

    文件存放目录
        方式1:日期
        方式2:用户
        方式3:文件个数
        方式4:随机目录
            mkdirs

例子
使用Servlet 3.0 完成文件上传

JSP

    <form action="${pageContext.request.contextPath}/Upload" method="post" enctype="multipart/form-data">
        <input type="text" name="name"><br>
        <input type="file" name="file"><br>
        <input type="submit" value="up">
    </form>

Servlet

@WebServlet("/Upload")
//1.添加文件上传注解
@MultipartConfig
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public UploadServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //2.设置编码
        request.setCharacterEncoding("utf-8");

        //3.获取属性值
        String name = request.getParameter("name");
        Part part = request.getPart("file");

        //4.获取请求头参数
        String contentDisposition = part.getHeader("Content-Disposition");

        //5.截取文件名
        String fileName = contentDisposition.substring(contentDisposition.indexOf("filename=") + 10, contentDisposition.length() - 1);

        //6.获得输入流
        InputStream in = part.getInputStream();

        //7.保存上传文件
        //1).放置到绝对路径
        //OutputStream out = new FileOutputStream(new File("D:\\Program Files\\Tomcat 8.5\\webapps\\servlet3_project\\upload\\"+fileName));

        //2).放置到服务器路径中,只要服务器重启文件就会丢失
        OutputStream out = new FileOutputStream(new File(this.getServletContext().getRealPath("/upload/"+fileName)));

        //8.拷贝文件
        IOUtils.copy(in, out);
        System.out.println("Copy Success");
    }


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

结果:

Copy Success

4.文件上传问题-文件重名

每一个客户端都可以进行文件上传操作,那么当我们上传的文件过多,一定会出现同名的文件,那么在服务器端只能保存一个,对于这个问题,我们在上传文件时,就需要考虑文件重名问题.

一般情况下,对于上传文件,为了保证不重名,会给文件起一个随机名.

  1. 一种方案是使用uuid.
  2. 一种方案是使用毫秒值

5.文件上传问题-存储位置

本质就是上传的文件是否允许浏览器端直接访问。
例如:商品添加时需要一个图片,这个图片一定是可以直接被浏览器端访问的。

允许被浏览器端访问:

放置在WebRoot下,但不能是WEB-INF或META-INF下其及子目录下

不允许被浏览器端访问:

若放在工程下则放置在WEB-INF或META-INF及其子目录下.
也可以不放在工程下

6.文件上传问题-目录分离

当我们上传文件过多,并且保存在同一个目录下时,我们就需要考虑怎样处理它们,因为一个目录下文件过多,不仅降低性能,操作时也不方便。

为了防止同一个目录下方上传文件数量过多

1) 按照上传时间进行目录分离 (周、月 )
2) 按照上传用户进行目录分离 ----- 为每个用户建立单独目录 
3) 按照固定数量进行目录分离 ------ 假设每个目录只能存放3000个文件 ,每当一个目录存满3000个文件后,创建一个新的目录
4) 按照唯一文件名的hashcode 进行目录分离  
  public static String generateRandomDir(String uuidFileName) {
        // 获得唯一文件名的hashcode
        int hashcode = uuidFileName.hashCode();
        // 获得一级目录
        int d1 = hashcode & 0xf;       
        // 获得二级目录
        int d2 = (hashcode >>> 4) & 0xf;
        return "/" + d2 + "/" + d1;// 共有256目录
    }

思维导图

这里写图片描述

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页