• Servlet


    Servlet简介

    Servlet是sun公司开发的一款动态Web技术

    把实现了Servlet接口的java程序叫Servlet

    构建Servlet

    新建一个Maven项目,删掉里面的src文件夹,这个空的工程就是Maven的主工程

    image-20210429215244032

    去导入相关的包

    image-20210429215558868

    image-20210429215920469

    放入pom.xml中,有红色报错就刷新

    image-20210429215645180

    由于是Servlet项目需要建一个Webapp

    image-20210429224707547

    这里路径每次都需要重新设置的话,可以参考https://blog.csdn.net/tanghuan0827/article/details/107023594

    image-20210429224844845

    image-20210429225056243

    关于Maven父子工程的理解:

    在父项目中会有

      <modelVersion>4.0.0</modelVersion>
    

    父项目中的JAR包子项目可以直接使用

    再新建两个文件夹

    image-20210429225555346

    Maven环境优化

    1.修改web.xml为最新的

    2.将maven架构搭建完整

    编写一个Servlet程序

    新建一个package里面新建java文件

    1.编写普通类

    2.实现Servlet接口,直接继承httpServlet

    以下是他们直接的关系

    public class HelloServlet extends HttpServlet {
    }
    public abstract class HttpServlet extends GenericServlet {
    }
    public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    }
    public interface Servlet {
        void init(ServletConfig var1) throws ServletException;
        ServletConfig getServletConfig();
        //主要方法
        void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
        String getServletInfo();
        void destroy();
    }
    

    为什么我们的程序是Servlet程序,因为继承了HttpServlet

    HttpServlet抽象类 继承了GenericServletGenericServlet实现了Servlet接口,因此我们自己的类只需要继承HttpServlet既可以。

    Servlet接口包含在GenericServlet中实现了,判断调用了什么类型方法,然后去调用默认实现

    image-20210429231742018

    最后类的编写为:

    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            PrintWriter writer = resp.getWriter();
            writer.print("Hello Servlet");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        }
    }
    

    3.编写Servlet的映射

    我们写的java程序,需要浏览器访问,浏览器需要连接Web服务器,所以我们需要在Web服务中注册我们写的Servlet,还需要浏览器能够访问的路径

      <!--注册Servlet-->
      <servlet>
          <!--名字和下面的相同就行-->
        <servlet-name>Hello</servlet-name>
         <!--项目下的类-->
        <servlet-class>com.ylc.HelloServlet</servlet-class> 
      </servlet>
      <servlet-mapping>
           <!--Servlet请求路径-->
        <servlet-name>Hello</servlet-name>
        <url-pattern>/hello</url-pattern>
      </servlet-mapping>
    

    4.配置Tomcat

    image-20210429235151662

    image-20210429235323155

    5.测试tomcat运行成功

    image-20210429235545373

    6.接下来访问映射的那个请求路径

    image-20210429235704527

    Servlet实现原理

    Serlvet是由Web服务器调用,Web服务器其收到六零看起请求之后会:

    image-20210503143547899

    Mapping

    匹配请求路径

      <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>/hello</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>/hello/*</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>.ylc</url-pattern><!--自定义后缀请求路径-->
      </servlet-mapping>
    

    *前面不能加任何项目路径

    优先级问题:指定了固定路径优先级最高

    ServletContext对象

    Web容器启动的时候,会为每一个Web程序都创建一个ServletContext对象,代表了当前应用

    共享数据

    在这个ServletContext保存的数据,在其他servlet可以拿到

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext=this.getServletContext();
        String username="ylc";
        servletContext.setAttribute("username",username);
    }
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext= this.getServletContext();
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        String username=(String) servletContext.getAttribute("username");
        resp.getWriter().print("名字:"+username);
    }
    
    <servlet>
      <servlet-name>GetC</servlet-name>
      <servlet-class>GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>GetC</servlet-name>
      <url-pattern>/getc</url-pattern>
    </servlet-mapping>
    <servlet>
      <servlet-name>hello</servlet-name>
      <servlet-class>helloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>hello</servlet-name>
      <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
    

    运行结果:

    image-20210506213639053

    请求转发

    A想要从C那里拿到东西,但是不能直接连接到C,只能通过B从C那里拿到东西,C给B,B再给A。

    这样A和C就不用会面,路径也不需要发生改变,这就是转发的概念

    重定向就是A找B要一个资源,B告诉A要去C那里拿,然后B就请求C资源

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        System.out.println("请求转发");
        servletContext.getRequestDispatcher("/getc").forward(req,resp);
    }
    

    读取资源文件

    <context-param>
      <param-name>url</param-name>
      <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext servletContext = this.getServletContext();
            String url = servletContext.getInitParameter("url");
            resp.getWriter().print(url);
        }
    

    image-20210506220514339

    读取资源文件

    Properties

    username="ylc"
    passworld=123
    

    在Java目录和resources中新建Properties都被打包到了同一个目录下:classes,俗称:classpath

    需要一个文件流

    读取不到资源是因为限定了资源的格式

    <build>
      <resources>
        <resource>
          <directory>src/main/resources</directory>
          <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
          </includes>
          <filtering>true</filtering>
        </resource>
        <resource>
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
          </includes>
          <filtering>true</filtering>
        </resource>
      </resources>
    </build>
    
    public class ServletText04  extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext servletContext = this.getServletContext();
            InputStream resourceAsStream = servletContext.getResourceAsStream("/WEB-INF/classes/db.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            String user=properties.getProperty("username");
            String passworld=properties.getProperty("passworld");
            resp.getWriter().print(user+":"+passworld);
        }
    }
    
    <servlet>
      <servlet-name>Pro</servlet-name>
      <servlet-class>ServletText04</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>Pro</servlet-name>
      <url-pattern>/Pro</url-pattern>
    </servlet-mapping>
    

    image-20210506224140855

    HttpServletRequest

    HttpServletResponse

    Web服务器接收到客户端的请求,如果要给客户端一些响应的消息用HttpServletResponse

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

    PrintWriter getWriter() throws IOException;
    ServletOutputStream getOutputStream() throws IOException;
    

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

    void setCharacterEncoding(String var1);
    void setContentLength(int var1);
    void setContentLengthLong(long var1);
    void setContentType(String var1);
    
    void setDateHeader(String var1, long var2);
    void addDateHeader(String var1, long var2);
    void setHeader(String var1, String var2);
    void addHeader(String var1, String var2);
    void setIntHeader(String var1, int var2);
    void addIntHeader(String var1, int var2);
    

    响应的状态码

    int SC_NOT_MODIFIED = 304;
    int SC_USE_PROXY = 305;
    int SC_TEMPORARY_REDIRECT = 307;
    int SC_BAD_REQUEST = 400;
    int SC_UNAUTHORIZED = 401;
    int SC_PAYMENT_REQUIRED = 402;
    int SC_FORBIDDEN = 403;
    int SC_NOT_FOUND = 404;
    int SC_METHOD_NOT_ALLOWED = 405;
    

    Response下载图片

    <web-app>
      <display-name>Archetype Created Web Application</display-name>
      <servlet>
        <servlet-name>fileServlet</servlet-name>
        <servlet-class>FileServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>fileServlet</servlet-name>
        <url-pattern>/fileServlet</url-pattern>
      </servlet-mapping>
    </web-app>
    
    public class FileServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //获取要下载文件的路径
            String path="E:\javaweb-servlet\FileServletText\src\resourse\1.jpg";
            //加载的文件名
            String filename=path.substring(path.lastIndexOf("\")+1);
            //让浏览器支持下载
            resp.setHeader("Content-Disposition","attachment; filename="+ URLEncoder.encode(filename,"UTF-8"));
            //获取下载的文件
            FileInputStream stream=new FileInputStream(path);
            //建立缓冲区
            int len=0;
            byte[] bytes=new byte[1024];
            //获取outputstream 向客户端写入数据
            ServletOutputStream outputStream = resp.getOutputStream();
            //将fileputputstream写入缓冲区
            while ((len=stream.read(bytes))>0)
            {
                outputStream.write(bytes,0,len);
            }
            stream.close();
            outputStream.close();
        }
    }
    

    image-20210508000438014

    重定向

    resp.sendRedirect();
    

    请求转发和重定向的区别:

    相同点:页面都会跳转

    不同点:

    重定向的时候url会发生变化 302

    转发的时候url不会发生变化 307

  • 相关阅读:
    Nginx
    Nginx & AWStats 安装、配置、使用
    Nginx
    linux
    工作中的 Vim 和 git
    后端
    django
    django
    awk流程控制
    linux系统内置函数
  • 原文地址:https://www.cnblogs.com/cg-ww/p/14825724.html
Copyright © 2020-2023  润新知