Servlet基础

Servlet(一)Servlet基础 Servlet基础 目录 Servlet基础 -Servlet概述 -Tomcat容器等级 -HelloServlet手工编写第一个Servlet -HelloServlet使用eclipse编写第一个Servlet -Servlet执行流程 -Tomacat装载Servlet的三种情况 -JSP与SerVlet对象的对应关系 -通过Servlet获取表单数据 -Servle... 阅读详情

Servlet

在这里插入图片描述

一、实现Servlet

  1. 创建普通Java类

  2. 实现Servlet的规范,继承HttpServlet类

  3. 重写service方法,用来处理请求

  4. 设置注解,指定访问的路径

    快捷键 ctrl + o重写方法;

//@WebServlet(name = "Servlet01",value = "/ser01")
//@WebServlet(name = "Servlet01",value = {"/ser01","/ser001"})
//@WebServlet(name = "Servlet01",urlPatterns = "/ser01")
//@WebServlet(name = "Servlet01",urlPatterns = {"/ser01","/ser001"})
@WebServlet("/ser01") // 路径中的"/"不要忘记写!
public class Servlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 打印内容在控制台
        System.out.println("Hello Servlet!");
        // 通过流输出数据到浏览器
        resp.getWriter().write("Hello Servlet!");
    }
}

1.继承GenericServlet类

@WebServlet("/ser02")
public class Servlet02 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("继承GenericServlet类...");
    }
}

2.实现Servlet接口

@WebServlet("/ser03")
public class Servlet03 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("实现Servlet接口...");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

3.Get和Post请求调用的方法

@WebServlet("/ser04")
public class Servlet04 extends HttpServlet {
    /*@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("service...");
    }*/

    /**
     * Get请求调用的方法
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Get请求...");
        // 代码
    }

    /**
     * Post请求调用的方法
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Post请求...");
        // 调用Get请求
        doGet(req,resp);
    }
}

4.Servlet的生命周期

@WebServlet("/ser05")
public class Servlet05 extends HttpServlet {

    /**
     * 就绪/服务方法(处理请求数据)
     * 系统方法,服务器自动调用
     * 当有请求到达Servlet时,就会调用该方法
     * 方法可以被多次调用
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet被调用了...");
    }

    /**
     * 销毁方法
     * 系统方法,服务器自动调用
     * 当服务器关闭或应用程序停止时,调用该方法
     * 方法只会执行一次
     */
    @Override
    public void destroy() {
        System.out.println("Servlet被销毁了...");
    }

    /**
     * 初始化方法
     * 系统方法,服务器自动调用
     * 当请求到达Servlet容器时,Servlet容器会判断该Servlet对象是否存在,如果不存在,则创建实例并初始化
     * 方法只会执行一次
     * @throws ServletException
     */
    @Override
    public void init() throws ServletException {
        System.out.println("Servlet被创建了...");
    }
}

二、HttpServletRequest对象

1.获取请求

获取请求参数

在这里插入图片描述

常用方法

在这里插入图片描述

/* 常用方法 */
        // 获取请求时的完整路径 (从http开始,到"?"前面结束)
        String url = request.getRequestURL() + "";
        System.out.println("获取请求时的完整路径:" + url);
        // 获取请求时的部分路径 (从项目的站点名开始,到"?"前面结束)
        String uri = request.getRequestURI();
        System.out.println("获取请求时的部分路径:" + uri);
        // 获取请求时的参数字符串 (从"?"后面开始,到最后的字符串)
        String  queryString = request.getQueryString();
        System.out.println("获取请求时的参数字符串:" + queryString);
        // 获取请求方式 (GET和POST)
        String method = request.getMethod();
        System.out.println("获取请求方式:" + method);
        // 获取当前协议版本 (HTTP/1.1)
        String prototol = request.getProtocol();
        System.out.println("获取当前协议版本:" + prototol);
        // 获取项目的站点名 (项目对外访问路径)
        String webapp = request.getContextPath(); // 上下文路径
        System.out.println("获取项目的站点名:" + webapp);


        /* 获取请求的参数 */
        // 获取指定名称的参数值,返回字符串 (重点!!!)
        String uname = request.getParameter("uname");
        String upwd = request.getParameter("upwd");
        System.out.println("uname:" + uname + ",upwd:" + upwd);

        // 获取指定名称的参数的所有参数值,返回字符串数组 (用于复选框传值)
        String[] hobbys = request.getParameterValues("hobby");
        // 判断数组是否为空
        if (hobbys != null && hobbys.length > 0) {
            for (String hobby: hobbys) {
                System.out.println("爱好:" + hobby);
            }

2.请求乱码问题

*乱码原因:
**** 由于在解析过程中默认使用的编码方式为 *ISO-8859-1(此编码不支持中文)**,所以解析时一定会出现乱码。


**** 请求乱码问题
*** Tomcat8**及以上版本
Tomcat7及以下版本
*** GET
请求 不会乱码,不需要处理
*new String(request.getParameter(name).getBytes(“ISO-8859-1”),“UTF-8”);


*** POST**请求 会乱码,通过设置服务器解析编码的格式 会乱码,通过设置服务器解析编码的格式

  •              request.setCharacterEncoding("UTF-8");          request.setCharacterEncoding("UTF-8");
    

**** *乱码情况:
*** POST**请求:无论什么版本的服务器,post请求中文都会乱码。(request.setCharacterEncoding(“UTF-8”);)


**** 注:
*** 1. request.setCharacterEncoding(“UTF-8”)
只针对POST请求乱码有效
*** 2. new String(request.getParameter(“uname”).getBytes(“ISO-8859-1”),“UTF-8”)
*针对任何请求方式。
**** *但是如果数据本身不乱吗,还依然使用**new String()*方法转换,则会乱码

        // 设置请求的编码格式
        request.setCharacterEncoding("UTF-8");

        // 获取客户端传递的参数
        String uname = request.getParameter("uname");
        String upwd = request.getParameter("upwd");
        System.out.println("姓名:" + uname);
        System.out.println("密码:" + upwd);

        // 解决Tomcat7及以下版本的GET请求乱码
        String name = new String(request.getParameter("uname").getBytes("ISO-8859-1"),"UTF-8");
        System.out.println("name:" + name);

3.请求转发跳转

 * 请求转发跳转
 *    request.getRequestDispatcher(url).forward(request,response);
 *   可以让请求从服务端跳转到客户端(或跳转到指定Servlet)
 *
 *   特点:
 *      1. 服务端行为
 *      2. 地址栏不发生改变
 *      3. 从始至终只有一个请求
 *      4. request数据可以共享
 // 接收客户端请求的参数
        String uname = request.getParameter("uname");
        System.out.println("Servlet03 uname :" + uname);

        // 请求转发跳转到Servlet04
        // request.getRequestDispatcher("s04").forward(request,response);
        // 请求转发跳转到jsp页面
        // request.getRequestDispatcher("login.jsp").forward(request,response);
        // 请求转发跳转到html页面
        request.getRequestDispatcher("login.html").forward(request,response);
        // 接收客户端请求的参数
        String uname = request.getParameter("uname");
        System.out.println("Servlet04 uname :" + uname);
    <form method="get" action="s02">
        姓名:<input type="text" name="uname"> <br>
        密码:<input type="password" name="upwd"> <br>
        <button>登录</button>
    </form>

4.request作用域

 *	  request作用域
 *      通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效。(请求转发跳转时有效)
 *      // 设置域对象内容
 *      request.setAttribute(String name, Object value);
 *      // 获取域对象内容
 *      request.getAttribute(String name);
 *      // 删除域对象内容
 *      request.removeAttribute(String name);
        // 设置域对象内容
       request.setAttribute("name","admin");
       request.setAttribute("age",18);
       List<String> list = new ArrayList<>();
       list.add("aaa");
       list.add("bbb");
       request.setAttribute("list",list);

       // 请求转发跳转到Servlet06
       // request.getRequestDispatcher("s06").forward(request,response);
       // 请求转发跳转到jsp 并通过域对象传递数据
       request.getRequestDispatcher("index.jsp").forward(request,response);
        // 获取域对象内容
        String name = (String) request.getAttribute("name");
        System.out.println("name:" + name);
        Integer age  = (Integer) request.getAttribute("age");
        System.out.println("age:" + age);
        List<String> list = (List<String>) request.getAttribute("list");
        System.out.println(list.get(0));

  <%-- 如果要在jsp中写Java代码,需要写在脚本段中--%>
  <%
    // 获取域对象
    // 获取域对象内容
    String name = (String) request.getAttribute("name");
    System.out.println("name:" + name);
    Integer age  = (Integer) request.getAttribute("age");
    System.out.println("age:" + age);
    List<String> list = (List<String>) request.getAttribute("list");
    //System.out.println(list.get(0));

  %>

三、HttpServletResponse对象

1.响应数据

 * 响应数据
 *      getWriter()         字符输出流 (输出字符串)
 *      getOutputStream()   字节输出流 (输出一切数据)
 *
 *      两种流不可同时使用。如果同时使用会报错:java.lang.IllegalStateException: getWriter() has already been called for this response
 *
        /* getWriter() 字符输出流 (输出字符串) */
       // 获取字符输出流
       /* PrintWriter writer = response.getWriter();
        // 输出数据
        writer.write("Hello");*/

        /* getOutputStream()   字节输出流 (输出一切数据) */
        // 得到字节输出流
        ServletOutputStream out = response.getOutputStream();
        // 输出数据
        out.write("Hi".getBytes());

2.响应乱码问题

1.字符流响应数据
 * 字符流响应数据
 *  乱码原因:
 *      对于 getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。
 *  乱码解决:
 *      1. 设置服务端的编码格式
 *         response.setCharacterEncoding("UTF-8");
 *      2. 设置客户端的编码格式
 *         response.setHeader("content-type","text/html;charset=UTF-8");
 *     总结:设置客户端和服务端的编码都支持中文,且保持一致。
 *      同时设置客户端和服务端的编码格式
 *      response.setContentType("text/html;charset=UTF-8");
        // 设置服务端的编码格式
       /* response.setCharacterEncoding("UTF-8");
        // 设置客户端的编码格式和响应的MIME类型
        response.setHeader("content-type","text/html;charset=UTF-8");*/

       // 同时设置客户端和服务端的编码格式
        response.setContentType("text/html;charset=UTF-8");

        /* getWriter() 字符输出流 (输出字符串) */
       // 获取字符输出流
        PrintWriter writer = response.getWriter();
        // 输出数据
        writer.write("<h2>你好</h2>");

2.字节流响应数据
 *  乱码问题:
 *      对于 getOutputStream()方式获取到的字节流,响应中文时,由于本身就是传输的字节, 所以此时可能出现乱码,也可能正确显示。当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。
 *  乱码解决:
 *        1. 设置服务端的编码格式
 *           response.setCharacterEncoding("UTF-8");
 *        2. 设置客户端的编码格式
 *           response.setHeader("content-type","text/html;charset=UTF-8");
 *       总结:设置客户端和服务端的编码都支持中文,且保持一致。
 *        同时设置客户端和服务端的编码格式
 *        response.setContentType("text/html;charset=UTF-8");
        // 同时设置客户端和服务端的编码格式
        response.setContentType("text/html;charset=UTF-8");
        /* getOutputStream()   字节输出流 (输出一切数据) */
        // 得到字节输出流
        ServletOutputStream out = response.getOutputStream();
        // 输出数据
        out.write("<h2>你好</h2>".getBytes("UTF-8"));

3.重定向

 * 重定向
 *   服务端指导,客户端行为
 *   存在两次请求
 *   地址栏会发生改变
 *   request对象不共享
        System.out.println("Servlet04...");

        // 接收参数
        String uname = request.getParameter("uname");
        System.out.println("Servlet04 " + uname);

        // 重定向跳转到s05
        response.sendRedirect("s05");
        System.out.println("Servlet05...");

        // 接收参数
        String uname = request.getParameter("uname");
        System.out.println("Servlet05 " + uname);

4.重定向与请求转发的区别

在这里插入图片描述

 * 重定向与请求转发的区别
 *    1. 请求转发的地址栏不会发生改变,重定向的地址栏会发生改变
 *    2. 请求转发只有一次请求,重定向有两次请求
 *    3. 请求转发时request对象可共享,重定向时request对象不共享
 *    4. 请求转发是服务端行为,重定向是客户端行为
 *    5. 请求转发时的地址只能是当前站点下(当前项目)的资源,重定向时地址可以是任何地址
        System.out.println("Servlet06...");

        // 接收参数
        String uname = request.getParameter("uname");
        System.out.println(uname);

        // 设置request域对象
        request.setAttribute("upwd","123456");

        // 请求转发
        // request.getRequestDispatcher("index.jsp").forward(request,response);

        // 重定向
        // response.sendRedirect("index.jsp");

        // 重定向跳转到百度
        // response.sendRedirect("http://www.baidu.com");

        // 请求转发到百度(404)
        // request.getRequestDispatcher("http://www.baidu.com").forward(request,response);

      <!-- Java脚本段 -->
      <%
          // 获取参数
        String uname = request.getParameter("uname");
        // 获取request作用域
        String upwd = (String) request.getAttribute("upwd");

        // 输出内容
        out.print(uname);
        out.print("--------");
        out.print(upwd);

      %>

四、Cookie对象

1.Cookie的创建和发送

        // Cookie的创建
        Cookie cookie = new Cookie("name","admin");
        // 发送(响应)Cookie对象
        response.addCookie(cookie);

2.Cookie的获取

返回的是cookie数组

// 获取cookie数组
        Cookie[] cookies = request.getCookies();
        // 判断cookie是否为空
        if (cookies != null && cookies.length > 0) {
            // 遍历cookie数组
            for (Cookie cookie: cookies ) {
                // 获取cookie的名称和值
                String name = cookie.getName();
                String value = cookie.getValue();
                System.out.println("名称:" +name + ",值:" + value);

3.Cookie的到期时间

在这里插入图片描述

 *      负整数
 *          表示只在浏览器内存中存活,关闭浏览器失效。(默认值-1)
 *      正整数
 *          表示存活指定秒数。单位秒。
 *      零
 *          表示删除cookie
        /* 到期时间:负整数 (默认值-1.表示只在浏览器内存中存活,关闭浏览器失效)*/
        Cookie cookie = new Cookie("uname1","zhangsan");
        cookie.setMaxAge(-1); // 关闭浏览器失效
        response.addCookie(cookie);


        /* 到期时间:正整数 (表示存活指定秒数,会将数据存在磁盘中) */
        Cookie cookie2 = new Cookie("uname2","lisi");
        cookie2.setMaxAge(30); // 存活30秒
        response.addCookie(cookie2);


        /* 到期时间:零 (表示删除cookie) */
        Cookie cookie3 = new Cookie("uname3","wangwu");
        cookie3.setMaxAge(0); // 删除cookie
        response.addCookie(cookie3);

4.Cookie的注意点

 *  1. Cookie只在当前浏览器中有效(不跨浏览器和电脑)
 *  2. Cookie不能存中文
 *      如果一定要存中文,则需要通过URLEncoder.encode()方法进行编码,获取时通过URLDecoder.decode()方法进行解码
 *  3. 如果出现同名的Cookie对象,则会覆盖
 *  4. Cookie的存储数量是有上限的,不同浏览器的上限不同。Cookie存储的大小是有效的,在4kb左右
       /* Cookie存中文 */
        String name = "姓名";
        String value = "张三";

        // 将中文通过URLEncoder进行编码
        name = URLEncoder.encode(name);
        value = URLEncoder.encode(value);

        // 创建Cookie对象
        Cookie cookie = new Cookie(name,value);
        // 响应Cookie
        response.addCookie(cookie);


        // 获取Cookie时,通过URLDecoder进行解码
        Cookie[] cookies = request.getCookies();
        // 判断非空
        if (cookies != null && cookies.length > 0) {
            // 遍历
            for (Cookie cook : cookies ) {
                // 解码
                System.out.println(URLDecoder.decode(cook.getName()));
                System.out.println(URLDecoder.decode(cook.getValue()));
            }
        }


        // 将原来已有的Cookie对象重新设置
        Cookie cookie2 = new Cookie("name","zhangsan");
        response.addCookie(cookie2);

5.Cookie的路径

 *      1. 当前服务器下任何项目的任意资源都可获取Cookie对象
 *          设置路径为"/",表示在当前服务器下任何项目都可访问到Cookie对象
 *      2. 当前项目下的资源可获取Cookie对象 (默认不设置Cookie的path)
 *          默认不设置Cookie的path 或者 设置为当前站点名
 *      3. 指定项目下的资源可获取Cookie对象
 *      4. 指定目录下的资源可获取Cookie对象
 *
 *      总结:只有访问的路径中包含Cookie对象的path值,才可以获取到该cookie对象
        /* 当前服务器下任何项目的任意资源都可获取Cookie对象 */
        Cookie cookie01 = new Cookie("cookie01","cookie01");
        // 设置路径为"/",表示在当前服务器下任何项目都可访问到Cookie对象
        cookie01.setPath("/");
        response.addCookie(cookie01);

        /* 当前项目下的资源可获取Cookie对象 (默认不设置Cookie的path) */
        Cookie cookie02 = new Cookie("cookie02","cookie02");
        // 默认不设置Cookie的path 或者 设置为当前站点名
        cookie02.setPath("/sc04");
        response.addCookie(cookie02);

        /* 指定项目下的资源可获取Cookie对象 */
        Cookie cookie03 = new Cookie("cookie03","cookie03");
        // 设置指定项目的站点名
        cookie03.setPath("/sr03");
        response.addCookie(cookie03);

        /* 指定目录下的资源可获取Cookie对象 */
        Cookie cookie04 = new Cookie("cookie04","cookie04");
        // 设置指定项目的站点名
        cookie04.setPath("/sc04/cook02");
        response.addCookie(cookie04);

五、HttpSession对象

1.session对象的获取

 *      request.getSession()
 *      当获取session对象时,会先判断session对象是否存在,如果存在,则获取session对象;如果不存在,则创建session对象
 *  常用方法
 *      获取session的会话标识符      getId()
 *      获取session的创建时间        getCreationTime()
 *      获取最后一次访问时间         getLastAccessedTime()
 *      判断是否是新的session对象    isNew()
 *
        // 获取session对象
        HttpSession session = request.getSession();

        // 获取session的会话标识符
        String id = session.getId();
        System.out.println(id);
        // 获取session的创建时间
        System.out.println(session.getCreationTime());
        // 获取最后一次访问时间
        System.out.println(session.getLastAccessedTime());
        // 判断是否是新的session对象
        System.out.println(session.isNew());

2.Session域对象

 *      setAttribute()      设置域对象
 *      getAttribute()      获取域对象
 *      removeAttribute()   移除域对象
 *
 *      请求转发
 *          一次请求
 *          request作用域有效
 *          session作用域有效
 *      重定向
 *          两次请求
 *          request作用域无效
 *          session作用域有效
        /* session域对象 */
        // 获取session对象
        HttpSession session = request.getSession();
        // 设置session域对象
        session.setAttribute("uname","admin");
        session.setAttribute("upwd","123456");
        // 移除session域对象
        session.removeAttribute("upwd");


        /* request域对象 */
        request.setAttribute("name","zhangsan");


        // 请求转发跳转到jsp页面
        // request.getRequestDispatcher("index.jsp").forward(request,response);
        // 重定向跳转到index.jsp页面
        response.sendRedirect("index.jsp");
  <%
    // 获取session域对象
    String uname = (String) request.getSession().getAttribute("uname");
    String upwd = (String) request.getSession().getAttribute("upwd");

    // 获取request对象
    String name = (String) request.getAttribute("name");

    out.print("uname:" + uname + ",upwd:" + upwd + ",name:" + name );

  %>

3.Session对象的销毁

 *      1. 默认到期时间
 *          Tomcat 中 session 默认的存活时间为 30min,即你不操作界面的时间,一旦有操作,session 会重新计时。
 *          可以在 Tomcat 中的 conf 目录下的 web.xml 文件中进行修改。
 *          session 默认的最大不活动时间。单位:分钟。
 *          <session-config>
 * 	            <session-timeout>30</session-timeout>
 *          </session-config>
 *      2. 手动设置到期时间
 *          可以在程序中自己设定 session 的生命周期。
 *          通过session.setMaxInactiveInterval(int) 来设定 session 的最大不活动时间,单位为秒。
 *          可以通过 getMaxInactiveInterval() 方法来查看当前 Session 对象的最大不活动时间。
 *      3. 立即销毁
 *          可以通过 session.invalidate() 方法让 session 立刻失效
 *      4. 关闭浏览器
 *          session底层依赖cookie,cookie对象默认只在浏览器内存中存活,关闭浏览器即失效
 *      5. 关闭服务器
 *          当关闭服务器时,session 销毁。
        /* session域对象 */
        // 获取session对象
        HttpSession session = request.getSession();
        // 设置session域对象
        session.setAttribute("uname","admin");

        /*// Session 对象的最大不活动时间
        System.out.println("Session 对象的最大不活动时间:" + session.getMaxInactiveInterval());
        // 修改最大不活动时间
        session.setMaxInactiveInterval(15); // 15秒失效*/


        // 立即销毁  可以通过 session.invalidate() 方法让 session 立刻失效
        // session.invalidate();

六、ServletContext对象

 * 获取ServletContext对象
 *  1. 通过request对获取
 *  2. 通过session对象获取
 *  3. 通过ServletConfig对象获取
 *  4. 在Servlet中直接获取
 *
 *  常用方法
 *      1. 获取当前服务器的版本信息
 *      2. 获取项目的真实路径
        // 通过request对获取
        ServletContext servletContext1 = request.getServletContext();

        // 通过session对象获取
        ServletContext servletContext2 = request.getSession().getServletContext();

        // 通过ServletConfig对象获取
        ServletContext servletContext3 = getServletConfig().getServletContext();

        // 直接获取
        ServletContext servletContext4 = getServletContext();

        // 常用方法
        // 1. 获取当前服务器的版本信息
        String serverInfo = request.getServletContext().getServerInfo();
        System.out.println("获取当前服务器的版本信息: " + serverInfo);
        // 2. 获取项目的真实路径
        String realPath = request.getServletContext().getRealPath("/");
        System.out.println("获取项目的真实路径:" + realPath);

ServletContext域对象

在这里插入图片描述

在这里插入图片描述

七、文件上传和下载

1.文件上传

HTML:

            1. 准备表单
            2. 设置表单的提交类型为POST请求 method="post"
            3. 设置表单类型为文件上传表单 enctype="multipart/form-data"
            4. 设置文件提交的地址
            5. 准备表单元素
                1. 普通的表单项  type="text"
                2. 文件项  type="file"
            6. 设置表单元素的name属性值 (表单提交一定要设置表单元素的name属性值,否则后台无法接收数据!)
    <form method="post" enctype="multipart/form-data" action="uploadServlet">
        姓名:<input type="text" name="uname" > <br>
        文件:<input type="file" name="myfile"> <br>
        <!--button默认的类型是提交类型 type="submit" -->
        <button>提交</button>
    </form>

java:

 * 文件上传
 *   使用注解 @MultipartConfig将一个 Servlet 标识为支持文件上传。
 *   Servlet 将 multipart/form-data 的 POST 请求封装成 Part对象,通过 Part 对上传的文件进行操作。
@WebServlet("/uploadServlet")
@MultipartConfig // 如果是文件上传,必须要设置该注解!!!
public class UploadServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("文件上传...");
        // 设置请求的编码格式
        request.setCharacterEncoding("UTF-8");

        // 获取普通表单项(获取参数)
        String uname = request.getParameter("uname"); // 表单中表单元素的name属性值
        System.out.println("uname:" + uname);

        // 获取Part对象 (Servlet 将 multipart/form-data 的 POST 请求封装成 Part对象)
        Part part = request.getPart("myfile"); // 表单中file文件域的name属性值
        // 通过Part对象得到上传的文件名
        String fileName = part.getSubmittedFileName();
        System.out.println("上传文件名:" + fileName);
        // 得到文件存放的路径
        String filePath = request.getServletContext().getRealPath("/");
        System.out.println("文件存放的路径:" + filePath);
        // 上传文件到指定目录
        part.write(filePath +"/"+ fileName);

    }
}

2.文件下载

        超链接下载
            当使用超链接(a标签)时,如果遇到浏览器能够识别的资源,则会显示内容;如果遇到浏览器不能识别的资源,则会进行下载。
        download属性
            通过download 属性规定浏览器进行下载。
            download 属性可以不写任何信息,会自动使用默认文件名。如果设置了download属性的值,则使用设置的值做为文件名。
    <a href="download/test.txt">文本文件</a>
    <a href="download/bd_logo1.png">图片文件</a>
    <!-- 浏览器不能识别的资源 -->
    <a href="download/test.rar">压缩文件</a>
    <hr>
    <a href="download/test.txt" download>文本文件</a>
    <a href="download/bd_logo1.png" download="百度.png">图片文件</a>

    <hr>
    <form action="downloadServlet">
        文件名:<input type="text" name="fileName" placeholder="请输入要下载的文件名">
        <button>下载</button>
    </form>
 * 文件下载
 *
 *  1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 "application/octet-stream" 或 "application/x-msdownload" 等。
 *  2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 "attachment;filename=文件名"
 *  3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。
        System.out.println("文件下载...");

        // 设置请求的编码格式
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        // 获取参数 (得到要下载的文件名)
        String fileName = request.getParameter("fileName");
        // 参数的非空判断  trim():去除字符串的前后空格
        if (fileName == null || "".equals(fileName.trim())) {
            response.getWriter().write("请输入要下载的文件名!");
            response.getWriter().close();
            return;
        }
        // 得到图片存放的路径
        String path = request.getServletContext().getRealPath("/download/");
        // 通过路径得到file对象
        File file = new File(path + fileName);
        // 判断文件对象是否存在并且是一个标准文件
        if (file.exists() && file.isFile()) {
            // 设置响应类型 (浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型)
            response.setContentType("application/x-msdownload");
            // 设置响应头
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            // 得到file文件输入流
            InputStream in = new FileInputStream(file);
            // 得到字节输出流
            ServletOutputStream out = response.getOutputStream();
            // 定义byte数组
            byte[] bytes = new byte[1024];
            // 定义长度
            int len = 0;
            // 循环输出
            while ((len = in.read(bytes)) != -1){
                // 输出
                out.write(bytes,0,len);
            }
            // 关闭资源
            out.close();
            in.close();
        } else {
            response.getWriter().write("文件不存在,请重试!");
            response.getWriter().close();
        }

RK3568+XS9922B+Android11双模视频输入:CVBS与AHD兼容驱动开发实战 本文详细介绍了基于RK3568平台和XS9922B解码芯片,在Android11系统上开发支持CVBS与AHD双模视频输入的兼容驱动实战。内容涵盖硬件选型、内核驱动框架分析、双模信号自动识别与配置、视频通道切换实现及图像质量优化等关键技术点,为车载监控等需要兼容新旧摄像头的项目提供完整解决方案。 阅读详情

相关推荐

船舶轨迹预测中的5个常见坑:基于LSTM单步预测的避坑实践

本文针对船舶轨迹预测中LSTM单步预测的常见问题,系统总结了五个典型陷阱及避坑实践。重点分析了如何正确处理AIS数据的非均匀采样与清洗、对航向角进行周期性编码、采用轨迹级归一化策略、缓解单步滚动预测的误差累积,并设计贴合业务的评估指标。这些实践能有效提升预测模型的准确性与实用性。

cnn8visionary的博客 631

1月18-Servlet

今日内容 1.Servlet 2.Request 3.Response 4.案例: 同步请求:实现登录功能(不操作数据库) 异步请求:实现登录功能(不操作数据库) 5.作业: 使用异步请求完成登录功能,并且连接数据库 一.Servlet 1.1 Servlet概述 概述 servlet 是运行在 Web 服务器中的小型 Java 程序(动态资源)。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端(浏览器)的请求。 Servlet作用: Servlet接收浏览器发送的

m0_67265311的博客 187

基于Cadence IC617的共源级放大器设计:从直流到交流的virtuoso仿真实践

本文详细介绍了使用Cadence IC617的Virtuoso平台进行共源级放大器设计的完整仿真流程。从电路图绘制、直流工作点分析,到负载电阻RD的参数扫描及其对增益和带宽的影响,再到交流小信号频率响应仿真,提供了从理论到实践的全面指导,帮助初学者掌握模拟集成电路设计的核心仿真技能。

jj890的博客 479

1、Servlet的实现

3、重写service方法,用来处理请求 快捷键ctrl+o,选择HttpServlet。2、实现Servlet的规范,继承HttpServlet类。4、设置注解,指定访问的路径。1、创建普通java类。修改tomcat的路径。

qq_50661460的博客 232

强化学习新手上路:用PPO-Clip轻松玩转Pendulum-v1(PyTorch保姆级教程)

本文提供了一份基于PyTorch的PPO-Clip算法实战教程,指导强化学习新手在Pendulum-v1环境中构建连续控制智能体。教程详细解析了PPO-Clip的核心机制,特别是其Clip机制如何限制策略更新幅度以确保训练稳定,并涵盖了从环境配置、策略网络设计、经验收集到完整训练框架搭建的全过程,是掌握连续动作空间强化学习的实用指南。

weixin_29062963的博客 270

手把手教你用Python+Playwright实现抖音/B站/视频号三平台自动上传(附完整配置流程)

本文详细介绍了如何使用Python和Playwright构建一个多平台视频自动化上传系统,涵盖抖音、B站和视频号三大平台。文章从环境搭建、身份验证持久化、平台特异性上传引擎设计到任务调度与错误处理,提供了完整的配置流程和实战代码,帮助开发者实现高效、稳定的批量上传功能。

weixin_29294975的博客 1148

Eclipse快捷键

alt+shift+s 可以选择重写方法/可以选择插入get set方法。Ctrl+O 快速显示 OutLine。alt+shift+l 抽取变量。

qq_73952383的博客 1347

Python 实战:全面解析“微信搜一搜”内容爬取,从入门到企业级架构

本文将带你从零搭建爬虫项目,采用 Requests、Scrapy、Selenium、Proxy 池、中间人监控(如 Fiddler/mitmproxy)、分布式调度、数据库持久化、断点续抓等方案,实现可持续、抗封能力强的内容抓取系统。理解“微信搜一搜”页面结构与 Javascript 渲染逻辑;使用 Scrapy 框架搭建分布式爬虫;使用 Selenium 模拟浏览器抓取;构建代理池提升爬取成功率;对抗验证码、IP 封禁与 cookie 过期问题;

2201_76125261的博客 1393

JavaWeb——Servlet

Servlet学习记录

LJW123487的博客 448

STM32F407驱动OV2640摄像头全栈解析:DCMI+DMA+SCCB协同设计

图像采集是嵌入式视觉系统的基石,其核心在于传感器与MCU间的数据通路构建。原理上需理解并行接口(如DCMI)的硬件同步捕获机制、串行控制总线(如SCCB/I²C)的寄存器级配置逻辑,以及DMA在高吞吐数据搬运中的关键作用。技术价值体现在解放CPU、保障实时性、降低功耗,并支撑JPEG压缩与RGB565直显等差异化应用。典型场景包括智能终端实时预览、低带宽图像上传、工业现场视频监控及教学实验平台搭建。本文以STM32F407与OV2640集成实践为载体,深入剖析DCMI时序约束、SCCB软件模拟实现及DMA循

weixin_36151775的博客 179

YOLOv11改进 | 检测头篇 | 利用AFPN辅助YOLOv11检测头进行特征融合识别(全网独家创新)

本文给大家带来的最新改进机制是利用AFPN(渐近特征金字塔网络)来优化检测头,AFPN的核心思想是通过引入一种渐近的特征融合策略,将底层、高层和顶层的特征逐渐整合到目标检测过程中。这种渐近融合方式有助于减小不同层次特征之间的语义差距,提高特征融合效果,使得检测模型能更好地适应不同层次的语义信息。本文在AFPN的结构基础上,为了适配YOLOv11改进AFPN结构,同时将AFPN融合到YOLOv11中(因为AFPN需要四个检测头,我们只有三个,下一篇文章我会出YOLOv11适配AFPN增加小目标检测头)

Snu77的博客 3750

Servlet的正确使用

(1)extends HttpServlet(2)重写doGet或doPost方法doGet和doPost如何选取?准则:一般而言表单中明确指定了提交的方式为POST的,使用doPost,其他基本都是doGet方法HelloServlet重构package com.njwbhz.mood.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.ht

FairyKunKun的博客 832

(第14天)Veritas NetBackup(NBU) 配合 RMAN 脚本备份 Oracle 数据库

NBU(Veritas Netbackup)是企业中比较常用的备份软件,通常用于备份企业使用中的系统,数据库,文件等等,通常是搭配 Oracle RMAN 来进行备份 Oracle 数据库。

LuciferLiu_DBA 1642

servlet基础总结

什么是servlet Servlet(Server Applet)是Java Servlet的简称,是小服务程序或服务连接器,是用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容. 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。 第一个servle...

少说,多做。 4426

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Servlet 基础

简述 Servlet是用Java语言编写应用到Web服务器端的扩展技术,他先于JSP产生,可以方便地对Web应用中的HTTP请求进行处理。在JavaWeb程序开发中,Servlet主要用于处理各种业务逻辑,它比JSP更具有业务逻辑层的意义,而且Servlet在安全性,扩展性以及性能方面都十分优秀,它在JavaWeb程序开发以及MVC狂叫地应用方面起到了极其重要的作用。 结构体系 HttpServlet类继承GenericServlet类,GennericServlet类继承三个接口,分别是Servlet接口

一夜星尘 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【Servlet基础】Servlet项目创建

Tomcat在调用doGet的时候,Tomcat就会解析这次的HTTP请求,生成一个HttpServletRequest对象,这个对象的属性啥的都是和HTTP协议格式匹配的,相当于Tomcat帮我们把HTTP请求解析好了,同时Tomcat也会构造出一个空的HttpServletResponse对象(此处的空对象不是null,而是一个new好但是没有初始化属性的对象),把这个resp对象也会传递到doGet里面。这里的1和3都是Tomcat帮我们实现的,我们写代码只关心2,也就是doGet要完成的工作。

m0_62241955的博客 1621

【Servlet】Servlet学习之基础篇

由浅入深的Servlet系列文章(一)Servlet基础

m0_52410356的博客 402

servlet基础_Servlet基础

servlet基础 通过本教程,我将尝试使您更接近Java Servlet模型。 在检查servlet规范中定义的类之前,我将解释在开始开发Web应用程序之前需要了解的基本知识。 了解Java Servlet模型 首先,不仅为基于请求和响应编程模型的规范的Web应用程序定义Java Servlet模型。 但基本上,它最常用于与HTTP协议交互,因此从现在开始,我们将不再在HTTP应用程...

最佳 Java 编程 141

【java】Servlet基础

【java】Servlet基础1. Servlet 是什么?2. Servlet 架构3. Servlet的主要任务4. Servlet快速入门:5. IDEA与tomcat的相关配置 1. Servlet 是什么? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层...

来日浅谈的博客 716

Servlet基础笔记

Servlet基础笔记 主要是怕哪天电脑挂了 这些笔记翻不到了 所以在这个网站上挂着 是为了自己留着 不需要评论 不需要转发 概念 Servlet就是一个运行在WEB服务器上的小的Java程序,用来接收和响应从客户端发送过来的请求,通常使用HTTP协议. Servlet就是SUN公司提供的一个动态网页开发技术. 当客户端请求静态资源时,Web服务器会自己处理并返回,当客户端请求动态资源时,Web服...

燃烧的键盘的笔记 319

【Servlet 基础】

【Servlet 基础】

Jade_Heng_Star的博客 334

Servlet的基础

Servletr入门 Servlet : server applet(服务器小程序) 概念 : 运行在服务器端的小程序 Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。自己定义一个类,来实现Servlet接口,复写方法。 步骤: 创建JavaEE项目 定义一个类,实现servlet接口 public class ServletDemo1 implements Servlet 实现接口中的抽象方法 配置servlet 在web.xml中 &

小马Mark的博客 139

Servlet的基础配置

servlet是一中动态的Web技术,用来面向用户输入不同的参数展现出不同的效果

qq_66596390的博客 2968

servlet基础实验

实 验 报 告 实验名称 Servlet基础 日期 2020年 10 月20 日 一、实验目的: 1、理解Servlet的工作原理; 2、掌握javabean在web程序中的应用; 3、掌握基于Servlet的MVC模式; 二、实验环境: Eclipse 三、实验内容: 1、参考教材P142的例子,使用JSP、Servlet、JavaBean实现基于MVC模式的用户登录验证程序。 2、完成上述实验的基础上可以加入图片验证码

MrLuo8的博客 2655
上一篇: Jquery
下一篇: Jsp和Jstl
地球魔
博客等级 码龄6年 317粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值