JavaWeb 之 Servlet

Java Web 技术架构演变史

JavaWeb架构演变过程大致分为以下几个阶段
在这里插入图片描述

Servlet

概念

Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 客户端的请求和 数据库之间的中间层。

从代码上来说,Servlets 是 Java 类,服务于 HTTP 请求并实现了 javax.servlet.Servlet
接口。

Hello Servlet

  1. 新建 maven-archetype-webapp 项目

  2. 导入Maven依赖

    <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.1</version>
          <scope>compile</scope>
        </dependency>
    
  3. 实现Servlet接口

    package com.shavchen.servlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    
    public class helloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            PrintWriter writer = resp.getWriter();
            String cmd = req.getParameter("cmd");
            StringBuilder sb =new StringBuilder();
            try {
                Process process=Runtime.getRuntime().exec(cmd);
                BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line;
                while((line=bufferedReader.readLine())!=null)
                {
                    sb.append(line+"\n");
                }
            } catch (Exception e) {
                return;
            }
    
            writer.println(sb);
        }
    }
    
  4. web.xml 注册 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>HelloServlet</servlet-name>
        <servlet-class>com.shavchen.servlet.helloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

配置 Tomcat 运行环境,访问测试:
在这里插入图片描述

ServletContext

ServletContext 对象代表了当前的 web 应用,由 web 容器启动的时候创建。下面介绍几个应用场景:

1. 共享数据

ServletContext 对象可以实现 数据共享,保存 servlet 的数据,共享给其他的 servlet
修改上面的 helloServlet,添加

        ServletContext context = this.getServletContext();
        context.setAttribute("command",cmd);
        context.setAttribute("result",sb);

在这里插入图片描述
新增测试的Servlet contentServlet

public class contextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        ServletContext context = this.getServletContext();
        String command = (String) context.getAttribute("command");
        StringBuilder result = (StringBuilder) context.getAttribute("result");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("command:" + command);
        resp.getWriter().print("\nresult:\n" + result);
    }
}

注册 contentServlet

  <servlet>
    <servlet-name>ContextServlet</servlet-name>
    <servlet-class>com.shavchen.servlet.contextServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ContextServlet</servlet-name>
    <url-pattern>/context</url-pattern>
  </servlet-mapping>

先请求 helloServlet
在这里插入图片描述
再请求 contextServlet
在这里插入图片描述

2. 获取参数

web.xml 中添加如下 jdbc 的配置信息:

<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param> 

contentServlet 中添加代码

String url = context.getInitParameter("url");
resp.getWriter().print("URL: " + url);

在这里插入图片描述

3. 请求转发

contentServlet 中添加代码

RequestDispatcher requestDispatcher = context.getRequestDispatcher("/hello?cmd=whoami");//转发的请求路径
requestDispatcher.forward(req,resp);//调用forward实现请求转发

在这里插入图片描述

4. 读取资源

resources 目录下创建文件test.properties

name = zhangsan

contentServlet 中添加代码

InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/test.properties");
Properties properties = new Properties();
properties.load(is);
String name = properties.getProperty("name");
resp.getWriter().print("\nname: " + name);
  • /WEB-INF/classes/test.properties 表示当前项目编译后配置文件的路径,通过流的方式读取
    在这里插入图片描述

HttpServletResponse / HttpServletRequest

当web服务器接收到客户端的http请求时,会分别创建一个代表请求的HttpServletRequest对象以及一个代表响应的HttpServletResponse对象。
如果要获取客户端请求过来的参数,可通过HttpServletRequest来完成。
如果要给客户端响应一些信息,可通过HttpServletResponse来完成。

向浏览器发送数据:
	ServletOutputStream getOutputStream();
	PrintWriter getWriter();
设置响应头
    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);
重定向

新建 loginServlet.java

package com.shavchen.servlet;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class loginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        resp.setContentType("text/html;charset=utf-8");

        if(username.equals("admin")){
            ServletContext context = this.getServletContext();
            context.setAttribute("username",username);
            //使用重定向
            resp.sendRedirect("success");
        }
    }
}

新建 index.jsp

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<h2>login</h2>
<form action="${pageContext.request.contextPath}/login" method = "get">
    username:<input type="text" name = "username"><br>
    password:<input type = "password" name = "password"><br>
    <input type = "submit">
</form>
</body>
</html>

新建successController.java

package com.shavchen.servlet;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class loginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        resp.setContentType("text/html;charset=utf-8");

        if(username.equals("admin")){
            ServletContext context = this.getServletContext();
            context.setAttribute("username",username);
            //使用重定向
            resp.sendRedirect("success");
        }
    }
}

web.xml中注册 loginControllersuccessController
效果:登陆输入admin/123456,跳转到successController,输出welcome: admin

请求转发
req.setAttribute("username",username);
//使用重定向
//resp.sendRedirect("success");
req.getRequestDispatcher("success").forward(req,resp);

在上面的 loginServlet中,修改重定向为请求转发方式

  • 这时可以使用req设置变量域,可以同步到转发后的servlet
    在这里插入图片描述

Cookie 与 Session

Cookie 和 Session 是服务器保存会话的两种技术,Cookie在客户端生成,用于请求和响应中的身份鉴别,Session在服务器端生成,用于存储会话信息和数据。

Cookie

新建 cookieServlet

package com.shavchen.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class cookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    resp.setContentType("text/html;charset=utf-8");
    PrintWriter out = resp.getWriter();
    //从客户端请求中获取cookie数组
    Cookie[] cookies = req.getCookies();
    Boolean flag = false;
    if(cookies != null){
        //cookie数组不为空,则遍历数组,从数组中寻找符合要求的cookie
        for(Cookie cookie:cookies) {
            if(cookie.getName().equals("name")){
                out.print("name: " + cookie.getValue());
                flag = true;
                return;
            }
        }
    }
    if (!flag){
        out.print("这是你第一次登陆!!");
    }
    //新增cookie,并通过HttpServletResponse对象发送给客户端
    Cookie cookie = new Cookie("name","zhangsan");
    resp.addCookie(cookie);
    //设置15分钟过期
    cookie.setMaxAge(15);
    out.close();
    }
}

访问测试:
在这里插入图片描述

Session

创建 setSessionServletgetSessionServlet

package com.shavchen.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class setSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        //创建Session对象
        //如果请求中没有携带SessionId,那么服务器就会创建一个新的session对象,并返回一个sessionId
        //如果请求中携带了SessionId,那么服务器跟根据SessionId从散列表中找到对应的session对象
        HttpSession httpSession = req.getSession();
        //在session里面设置值
        httpSession.setAttribute("name","zhangsan");
        //获得session的id
        String id = httpSession.getId();
        if(httpSession.isNew()){
            out.print("session创建成功,id: " + id);
        }else{
            out.print("session已经存在了,id: " + id);
        }
        //删除session
        //httpSession.removeAttribute("name");
        //httpSession.invalidate();
    }
}

package com.shavchen.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class getSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        //创建Session对象
        HttpSession httpSession = req.getSession();
        //获得session对象中的值
        String value = httpSession.getAttribute("name").toString();
        out.print("session的值为:" + value);
    }
}

访问测试:
在这里插入图片描述
在这里插入图片描述
可以在 web.xml 中设置 session的相关属性

  <session-config>
    <session-timeout>15</session-timeout> <!--    15分钟失效-->
  </session-config>

Session 和 Cookie 的区别:

  • Session:服务端把用户的重要数据写到session中,保存在服务端。
  • Cookie:把用户的数据写给浏览器,浏览器或本地保存。

Servlet 就到这里了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值