狂神说JavaWeb-Servlet篇

Servlet简介

Servlet是sun公司开发动态web的一门技术

Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需完成下面两步:

编写一个类,实现Servlet接口

把开发好的Java类部署到Web服务器中

把实现了Servlet接口的Java程序叫做Servlet

二、构建一个Servlet项目

Servlet接口Sun公司有两个默认的实现类:HttpServlet、GenericServlet

分析源码:

Servlet源码分析

http://t.csdn.cn/b2d3E

编写程序

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hello Servlet");
//        resp.setContentType("");
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer = resp.getWriter();
        writer.println("Hello Servlet");
    }

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

编写Servlet映射

为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">



  <!--  注册Servlet-->
  <servlet>
    <!--    匿名-->
    <servlet-name>hello</servlet-name>
    <!--    完整类名-->
    <servlet-class>com.sv.HelloServlet</servlet-class>
  </servlet>
  <!--  servlet请求路径-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <!--    访问该Servlet的虚拟路径,该路径以/开头,代表应用程序的根目录-->
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>


  <servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.sv.ErrorServlet</servlet-class>

  </servlet>
  <!--  servlet请求路径-->
  <servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>


</web-app>

Servlet原理

Servlet是由Web服务器(tomcat)调用,web服务器(tomcat)在收到浏览器请求之后,会:

Mapping问题

#注意:*前面不能加项目映射的路径

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

<url-pattern>/hello</url-pattern>

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

<url-pattern>/hello</url-pattern>

<url-pattern>/hello1</url-pattern>

<url-pattern>/hello2</url-pattern>

3、一个Servlet可以指定通用映射路径

<url-pattern>/*</url-pattern>

4、指定一些后缀或者前缀等等

5、优先级问题

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

二、ServletContext(后期不会使用,但为后期开发做铺垫,属于后期的影子)

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

1、共享数据(后期用session去做)

我在这个Servlet中保存的数据,可以在另一个Servlet中拿到

代码示例:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.sv.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>


  <servlet>
    <servlet-name>gets</servlet-name>
    <servlet-class>com.sv.GetServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>gets</servlet-name>
    <url-pattern>/gets</url-pattern>
  </servlet-mapping>


</web-app>

发送端Servlet:

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username="杨朋";
        context.setAttribute("username",username);
        System.out.println("hello");
    }

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

接收端Servlet:


public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        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 {
        this.doGet(req,resp);
    }
}

#注意:text/html的意思是将文件的content-type设置为text/html的形式,浏览器在获取到这种文件时会自动调用html的解析器对文件进行相应的处理。

2、获取初始化参数

配置xml

<!--  设置一些web应用的初始化参数-->
  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybaits</param-value>
  </context-param>
  <servlet>
    <servlet-name>db</servlet-name>
    <servlet-class>com.sv.ServletDemo03</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>db</servlet-name>
    <url-pattern>/db</url-pattern>
  </servlet-mapping>

编写程序:

public class ServletDemo03 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       
        ServletContext context = this.getServletContext();
        String s = context.getInitParameter("url");
        resp.getWriter().print(s);
    }

3、请求转发(后期用request去做)

请求转发寻求路径A-C模型:

重定向寻求路径A-C模型:

编写xml:

 <servlet>
    <servlet-name>co</servlet-name>
    <servlet-class>com.sv.Servletemo04</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>co</servlet-name>
    <url-pattern>/co</url-pattern>
  </servlet-mapping>

编写程序:

public class Servletemo04 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
//        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/db");  //转发的请求路径
//        requestDispatcher.forward(req,resp);   //调用forward实现请求转发
        context.getRequestDispatcher("/db").forward(req,resp);
    }

4、读取资源文件(后期会用反射和类加载器)

Properties

在Java目录下新建properties

在resources目录下新建properties

发现:都被打包到了同一路径下:classes,我们俗称这个路径为classpath(类路径)

思路:需要一个文件流

xml配置:

  <servlet>
    <servlet-name>po</servlet-name>
    <servlet-class>com.sv.ServletDemo05</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>po</servlet-name>
    <url-pattern>/po</url-pattern>
  </servlet-mapping>

编写程序:

public class ServletDemo05 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");

        Properties properties = new Properties();
        properties.load(is);
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        resp.getWriter().print(username+";"+password);
    }

六、HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse

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

如果要给客户端相应一些信息:找HttpServletResponse

1、简单分类

负责向浏览器发送数据的方法(追溯源码ServletResponse )

ServletOutputStream getOutputStream() throws IOException;

    PrintWriter getWriter() throws IOException;

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

响应状态码

2、常见应用

1、像浏览器输出消息

2、下载文件

1、要获取下载文件的路径

2、下载的文件名是啥?

3、设置想办法让浏览器能偶支持下载我们需要的东西

4、获取下载文件的输入流

5、创建缓冲区

6、获取OutputStream对象

7、将FileOutputStream流写入到buffer缓冲区

8、使用OutputStream将缓冲区中的数据输出到客户端

测试:

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1、要获取下载文件的路径
        String realPath = "E:\\Code\\JavaCode\\java-web-servlet\\servlet02\\target\\classes\\src=http___i0.hdslb.com_bfs_article_d75e90f804db9b156bc77fe90bd5e38d6bc43141.jpg&refer=http___i0.hdslb.png";
        System.out.println("下载文件的路径"+realPath);

//        2、下载的文件名是啥?
        String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);

//        3、设置想办法让浏览器能偶支持下载我们需要的东西
        resp.setHeader("Content-Disposition","attachment;filename"+filename);

//        4、获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);

//        5、创建缓冲区
        int len=0;
        byte[] buffer = new byte[1024];

//        6、获取OutputStream对象
        ServletOutputStream out = resp.getOutputStream();

//        7、将FileOutputStream流写入到buffer缓冲区      8、使用OutputStream将缓冲区中的数据输出到客户端
        while ((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }

2、验证码

3、重定向

B一个web资源收到客户端A请求后,B它会通知A客户端去访问另一个web资源C,这个过程叫重定向

常见场景:

       *  用户登录

       

resp.sendRedirect("转发路径");

测试:

public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("/servlet02_war/down");
    }

七、HttpServletRequest

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

1、获取前端传递参数

req.getParameter()
req.getParameterValues()

2.测试

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

        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbys = req.getParameterValues("hobbys");

        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));
        System.out.println("================");
        System.out.println(req.getContextPath());
        //通过请求转发
        //这里的/代表当前的web应用
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }


<h1>登录</h1>
<div style="text-align: center">
<form action="${pageContext.request.contextPath}/login" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    爱好:
    <input type="checkbox" name="hobbys" value="女孩">女孩
    <input type="checkbox" name="hobbys" value="代码">代码
    <input type="checkbox" name="hobbys" value="唱歌">唱歌
    <input type="checkbox" name="hobbys" value="电影">电影

    <br>
    <input type="submit">
</form>
</div>

面试题:请你聊聊重定向和转发的区别

相同点

页面都会实现跳转

不同点

请求转发的时候,url不会产生变化   307

重定向的时候,url地址栏发生变化   302

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值