Servlet

Servlet

HelloServlet

1、构建一个普通的Maven项目,这个空的工程就是主工程

2、关于Maven父子工程的理解:

​ 父项目中会有:

<modules>
    <module>Servlet</module>
</modules>

​ 父项目中的java子项目可以直接使用

3、Maven环境优化

  • 将maven的结构搭建完整(添加java包和resourse包)

4、编写一个servlet程序

  • 编写一个普通类

  • 实现Servlet接口,直接继承HttpServlet

    public class HelloServlet extends HttpServlet {
        //重写方法 快捷键alt+insert
        //post和get可以相互调用
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            PrintWriter writer = resp.getWriter();//响应流
            writer.print("hello servlet");
        }
    }
    

5、编写Servlet的映射:把Java程序映射为可以被浏览器访问的路径

<web-app>
  <display-name>Archetype Created Web Application</display-name>

<!--  注册servlet-->
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>pers.luo.servlet.HelloServlet</servlet-class>
  </servlet>
<!--  servlet的请求路径-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

6、配置Tomcat

7、启动测试

Mapping原理

1、一个Servlet可以指定一个或多个映射路径

2、一个Servlet可以指定带*的映射路径,指定前缀或后缀路径

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
<!--    注意:*前面不能加/-->
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

3、优先级问题:指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求

ServletContext

Web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表当前的应用,利用ServletContext可以实现:

  • 共享数据 在一个servlet中保存的数据,可以在另一个servlet中获取

    1、在一个Servlet中放置数据

    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //资源
            String username = "张三";
            //获取ServletContext对象
            ServletContext context = this.getServletContext();
            //将资源放进context中
            context.setAttribute("username",username);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

​ 2、在另一个Servlet中读取数据

  ```java
  public class GetServlet extends HttpServlet {
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //获取ServletContext对象,所有的Servlet获取的是同一个
          ServletContext context = this.getServletContext();
          //获取资源
          String username = (String) context.getAttribute("username");
  
          //设置编码格式,能够输出中文
          resp.setContentType("text/html");
          resp.setCharacterEncoding("utf-8");
          //打印
          resp.getWriter().print("名字:"+username);
  
      }
  
      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          doGet(req, resp);
      }
  }
  ```

3、配置web.xml
<web-app>
  
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>pers.luo.servlet.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>getName</servlet-name>
    <servlet-class>pers.luo.servlet.GetServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>getName</servlet-name>
    <url-pattern>/getName</url-pattern>
  </servlet-mapping>
  
</web-app>

​ 4、测试结果

  • 请求转发(转发后路径不会变)

  • 读取资源文件

    注意:在java和resource路径下新建的文件都会被打包到classes中

​ 1、准备一个文件流

    ```pr
    username = root
    password = 123456
    ```

​ 2、读取文件流

   ```java
   public class GetProp extends HttpServlet {
       @Override
       protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
       }
   
       @Override
       protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           //获取数据流
           InputStream stream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/properties");
           //利用properties对象处理流
           Properties prop = new Properties();
           prop.load(stream);
           String username = prop.getProperty("username");
           String password = prop.getProperty("password");
   
           //输出
           resp.getWriter().println(username+":"+password);
       }
   }
   ```

​ 3、配置xml

​ 4、测试

HttpServletResponse

web服务器收到客户端的http请求,针对这个请求,分别创建一个HttpServletResponse和HttpServletRequest;

  • 如果要获取客户端请求过来的参数:HttpServletRequest

  • 如果要给客户端响应:HttpServletResponse

    1、简单分类

    负责向浏览器发送数据方法:

    • getOutputStream()

    • getWriter() 一般输出中文时使用

    负责向浏览器发送响应头的方法:

    • setCharacterEncoding()

    • setContentType()

    2、常见应用

    向浏览器输出消息;

    下载文件:

    public class FileDownload extends HttpServlet {
       @Override
       protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           //获取下载文件的绝对路径
           String path = "D:\\Code\\HelloServlet\\HttpResponse\\src\\main\\resources\\数据";
           System.out.println("下载文件的路径"+path);
          //下载的文件名是啥?利用字符串截取
           String filename = path.substring(path.lastIndexOf("\\") + 1);
         //让浏览器能够支持下载,注意文件名是中文需要用URLEndoder转码
           resp.setHeader("Content-disposition","attachment;filename"+ URLEncoder.encode(filename,"UTF-8"));
           //获取下载文件的输入流
           FileInputStream fileInputStream = new FileInputStream(path);
           // 创建缓冲区
           int len = 0;
           byte[] buffer = new byte[1024];
           //获取OutputStream对象
           ServletOutputStream outputStream = resp.getOutputStream();
           //将fileInputStream流写入buffer缓冲区,使用OutputSteam将缓冲区中的数据输出到客户端
           while ((len = fileInputStream.read(buffer))!= -1){
               outputStream.write(buffer,0,len);
           }
           //关闭流
           fileInputStream.close();
           outputStream.close();
       }
    
       @Override
       protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           doGet(req, resp);
       }
    }
    

实现重定向:

​ 一个Web资源收到客户端请求后,它会通知客户端去访问另一个Web资源,这个过程就叫重定向。常见场景:用户登录

​ 使用:resp.sendRediret();注意url中加入项目名

HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过http访问服务器,http中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest可以获得客户端请求的所有信息

  • 获取前端传递的参数以登录页面为例

1、在webapp下准备一个登录前端页面和登录成功前端页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
    <meta http-equiv="Content-Type"
          content="text/html; charset=ISO-utf-8">
</head>
<style>
    #a {
        width:50%;
        height:200px;
        border: 1px dashed ;
        background-color:lightyellow;
        text-align:center;
    }
    body{
        background-color:lightblue;
    }
</style>
<body>
<div id="a">
    <h1>登录界面</h1>
    <%--    action属性规定当提交表单时,向何处发送表单数据。--%>
    <form action="/R/login" method="post">
        账号:<input type="text" name="id"/>
        <br>
        密码:<input type="password"name="password"/>
        <br>
        <input type="submit" value="login"/>
    </form>
</div>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>
    <h1>登录成功</h1>
</body>
</html>

2、写login的servlet

public class Login extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取前端传递的参数
        String id = req.getParameter("id");
        String password = req.getParameter("password");
        System.out.println(id);
        System.out.println(password);
        //请求转发,也可以用重定向resp.sendRedirect("/R/success.jsp");
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }

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

3、注册servlet

  <servlet>
    <servlet-name>login</servlet-name>
    <servlet-class>pers.luo.servlet.Login</servlet-class>
  </servlet>
<servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/login</url-pattern>
</servlet-mapping>

Cookie、Session

会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话

服务端给给客户端一个信件,客户端下次访问服务端带上信件就可以:cookie

客户端技术(响应,请求),例子:保存用户上次访问时间

public class cookie extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //从客户端获取cookie
        Cookie[] cookies = req.getCookies();

        PrintWriter out = resp.getWriter();
        //检测cookie是否存在
        if(cookies != null){
           //遍历cookies
            for (Cookie cookie : cookies) {
                //注意此处equals()不能换成==
                if(cookie.getName().equals("lastlogintime")){
                    //将时间戳转化为date类型
                    long lastlogintime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastlogintime);
                    out.write("您上次访问的时间是:"+date.toLocaleString());
                }
            }
        }else{
            out.write("您是第一次访问此网页");
        }

        //服务端更新cookie,注意cookie的key用中文会报错;
        // System.currentTimeMillis()是系统当前时间,注意转化成String
        resp.addCookie(new Cookie("lastlogintime",System.currentTimeMillis()+""));
    }
}

session

服务器登记你来过了,下次你来时我来匹配你:session

服务器技术,利用这个技术,可以保存用户的会话信息?我们可以把信息和数据放在session中

服务器会给每个用户(浏览器)创建一个session对象,一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在。

posted @ 2023-03-13 16:46  奚罗罗  阅读(18)  评论(0编辑  收藏  举报