Servlet

Servlet_第1张图片

目录

​编辑一、Servlet 是什么

二、第一个 Servlet 程序

1、创建项目

2、引入依赖

3、创建目录

4、编写代码

5、打包程序

6、部署操作

7、验证 

小结:

三、更方便的部署方式

四、访问出错怎么办

五、Servlet 常用 API

1、HttpServlet

(1)init

(2)destroy

(3)service

 2、HttpServletRequest

3、HttpServletResponse

 六、前端给后端传参

1、GET,query string

2、POST ,form

3、POST ,json

七、、Cookie 和 Session

八、模拟登录的代码


一、Servlet 是什么

Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序员的 API, 帮助程序员简单高效的开发一个 web app.

网页分为两种:

静态页面:页面的内容始终是固定不变的

动态页面:页面的内容随着输入参数的不同而改变

静态页面,就只是单纯的 html ,而动态页面则是 html + 数据


二、第一个 Servlet 程序

老规矩,先写一个 hello world

预期写一个 servlet 程序,部署到 tomcat 上,通过浏览器访问,得到 hello world 字符串

一共七个步骤:

1、创建项目

2、引入依赖

3、创建目录结构

4、编写代码

5、打包程序

6、部署程序

7、验证


1、创建项目

此处,我们要创建一个 maven 项目

maven :是一个 “工程管理” 工具

1、规范目录结构

2、管理依赖

3、构建

4、打包

5、测试

........

我们现在,主要使用 管理依赖 和 打包 功能

Servlet_第2张图片

选择 maven ,然后创建新的项目即可

如果是首次使用 maven ,项目创建好了之后,会在下面读条,从中央仓库加载一些 maven 依赖

(需要联网,由于 maven 仓库在国外,网络不是很稳定,所以这里的读条会比较久)

注意此处的 目录结构:

Servlet_第3张图片


2、引入依赖

这里我们所需要引入的依赖就是 servlet 对应的 jar 包

在  maven 的官网中,搜索 servlet ,然后选择所需要的对应的版本

这里我选择的是 3.1.0的版本(和 tomcat 8 对应)

Servlet_第4张图片

 在这里,我们将这一段代码复制,粘贴到 pom.xml 中Servlet_第5张图片

 注意:粘贴的时候,要注意加一个 dependencies 标签

dependencies 这个标签是 project 顶级标签的子标签,位置不能放错,如果有多个依赖,都往标签里粘贴就行

如果是首次使用,此时这里的字可能是红色的,红色说明还没下载完,一般只要一粘贴,idea 的 mave 就会自动触发依赖的下载,下载完毕就不红了(下载只需要一次)

如果过了很久还没下载完,可以点一下刷新


3、创建目录

虽然 maven 已经帮我们自动的创建了一些目录,但是还不够

因为此处是需要 maven 去开发一个 web 程序,还需要别的目录

创建步骤:

(1)在 main 目录下(和 java ,resources 并列),创建一个 webapp 目录

(2)在 webapp 下创建 WEB-INF 目录

(3)在 WEB-INF 目录下,创建一个 web.xml 文件

(4)给 web.xml 写一点东西进去

Servlet_第6张图片

注意:此处目录名字和结构,一点都不能出错

web.xml 内容: 



        Archetype Created Web Application

当前写的 servlet 程序和以往写的别的代码相比,有一个非常大的区别:没有 main 方法!!!

main 方法可以视作是汽车的发动机,有了发动机才能跑

如果现在有一辆车,没有发动机,怎么跑呢?

挂一个车头,让车头拽着他跑就行了!!!

我们写的 servlet 程序就是车厢,tomcat 就是车头

把我们写好的 servlet 程序扔到 webapps 目录下,就相当于把车厢给挂在车头后面了

tomcat 如何识别 webapps目录下,哪些是需要拉着跑的车厢呢

就是靠目录下有一个 WEB-INF / web.xml,这个文件的作用就是让 tomcat 能够识别当前代码为 webapp,并进行加载


4、编写代码

我们先创建一个类,继承自 HttpServlet 

HttpServlet 是 servlet api 里提供的现成的类,写 servlet 代码一般都是继承这个类

这里继承的主要目的是为了针对 HttpServlet 进行功能的扩展 

接下来,重写 doGet 方法

Servlet_第7张图片

我们写的这个 doGet 方法,不需要我们自己手动调用,而是交给 tomcat 来调用,tomcat 收到一个 get 请求,就会触发 doGet 请求

Tomcat 就会构造好两个参数 req 和 resp

req 是 TCP socket 中读出来的字符串,按照 HTTP 协议解析得到的对象

这个对象里的属性是什么?

就是 和 HTTP 请求报文格式相对应的

resp 就是一个空的对象(不是 null,只是 new 了一个对象,但是没有设置属性),程序员就需要在 doGet 里面,根据 req ,结合自己的业务逻辑,构造出一个 resp 对象

doGet 做的工作就是根据请求,计算响应,其中 resp 这个参数,本质上就是一个 ”输出型参数“

此处的 Writer 对象是属于 resp 对象的,此时进行的 write 操作其实是往 resp 的 body 部分进行写入,等 resp 对象构造好了,tomcat 会统一的转成 HTTP 响应的格式,再写 socket

流对象,不一定是非得写入网卡,也不一定非得写入硬盘,也可以写到内存缓冲区里面(关键是看你代码实现的细节)

最后,再加上注解

注解是 java 中特殊的类,java 专门定义了一种 “语法糖” 来实现注解

注解的作用:针对一个 类 / 方法 ,进行额外的 “解释说明” ,赋予这个 类 / 方法 额外的功能 / 含义

此处的 @WebServlet 注解,作用是把当前的 类 和一个 HTTP 请求的路径关联起来

doGet 是 Tomcat 收到 GET 请求的时候就会调用,但是具体是不是要调用 doGet ,还得看当前 GET 请求的路径是什么,不同的路径可以触发不同的代码(关联到不同的类上面)

一个 Servlet 程序中,可以有很多的 Servlet 类,每个 Servlet 类,都可以关联到不同的路径(对应到不同的资源),因此此处多个 Servlet 就实现了不同的功能

@WebServlet ("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //这个是在服务器的控制台里打印
        System.out.println("hello world!");
        //要想把 hello world 返回到客户端,需要使用下面代码:
        //getWriter 会得到一个 Writer 对象
        resp.getWriter().write("hello world1");
    }
}

5、打包程序

这里所谓的打包程序,就是把程序编译好,得到一些 .class 文件

再把这些 ,class 打成一个压缩包

jar 包就是一种 .class 构成的压缩包

但是此处我们要打的是 war 包

jar 包只是一个普通的 java 程序,war 则是 tomcat 专属的用来描述 webapp 的程序

一个 war 包,就是一个 webapp

借助 maven ,直接点击即可

打开 maven 面板,然后选中 package,直接双击或者右键运行都可

Servlet_第8张图片

如果创建成功,就会显示 BUILD SUCCESSServlet_第9张图片

打包完毕之后,包会生成在 target 目录下Servlet_第10张图片

默认情况下,maven 打的是 jar 包,此处我们需要打 war 包,因此需要微调一下 pom.xml

这个就描述了 打的包是 jar 包还是 war 包

这个则描述了打的 war 包的名字(可以不写)

调整完毕之后,我们再重新进行打包

Servlet_第11张图片

此时,war 包就打成功了


6、部署操作

把刚才打包好的 war 拷贝到 tomcat 的 webapps 目录中即可

无论 tomcat 是再同一个还是不同的电脑上,都是这样进行拷贝的

然后,启动 tomcat 

如果 tomcat 正在运行,直接拷贝,tomcat 也能识别,但是这个识别操作可能存在 bug

当启动成功后,就说明当前的部署操作成功了


7、验证 

打开浏览器,输入 url,访问写好的这个代码

注意这个 URL 路径的写法:

第一级路径,也叫做 context path / application path(这个目录就代表一个 webapp 网站)

对应到我们刚才所打的 war 包的名字

第二级路径,也叫做 Servlet path ,就对应到代码中的注解


小结:

刚才在 浏览器地址栏中输入 URL 之后,浏览器就构造了一个对应的 HTTP GET 请求,发给了 tomcat

tomcat 就根据 第一级路径 去确定了具体的 webapp ,再根据 第二级路径 确定调用了哪个类 

再然后通过 GET / POST 方法确定调用了 HelloServlet 的哪个方法(doGet / doPost)

此时,tomcat 就执行对应的代码完成对应的工作


三、更方便的部署方式

上述步骤,是使用 Servlet 最朴素的步骤,我们也可以通过一些操作来简化步骤

打包和部署程序这两个操作,我们可以使用 IDEA 的 Tomcat 插件,把 Tomcat 集成到 IDEA 中,这样就省去了手动打包,手动部署的部分,只需要按一下运行,就可以自动打包部署

基于 Tomcat 插件自动打包部署,适用于开发阶段,频繁修改代码频繁验证

手动打包手动部署,适用于上线阶段,发布程序

IDEA 功能虽然很强,但是也不是面面俱到的

IDEA 提供了一些 API ,可以让程序员开发插件,对 IDEA 的现有功能进行扩展

很多程序都是有插件功能的Servlet_第12张图片

这个就是我们所需要用到的插件 

首次使用 Tomcat 插件,需要进行配置:

1、新增运行配置

 2、点击加号,新增配置

Servlet_第13张图片

3、设置一下 Tomcat 所在的路径

Servlet_第14张图片

 4、运行 Tomcat 

正常情况下,点击之后,IDEA 就会调用 tomcat 来运行程序了

smart tomcat 工作原理:

并不是自动把 war 包拷贝了(webapps 里面是不变的),而是通过另一种方式来启动 tomcat 的

tomcat 支持启动的时候,显示指定一个特定的 webapp 目录,相当于是让 tomcat 加载单个 webapp 运行

idea 直接调用 tomcat ,tomcat 直接加载当前项目中的目录

这个过程其实没有打 war 包,也没有 拷贝,也没有解压缩的过程

此时,程序是可以正常运行的,但是像之前 webapps 下已有的一些内容,比如说像欢迎页面,是没有的


四、访问出错怎么办

出现 404:

Servlet_第15张图片

1、路径写错了

2、你的 webapp 没有正确被部署

 出现 405:

1、比如 浏览器发了一个 GET 请求,但是你的代码里面没有写 toGet

2、super.doGet 没有干掉

出现 500:

代码抛异常了

出现 “空白页面” 

Servlet_第16张图片 代码里面没有写 resp.getWriter.write();

出现 “无法访问此网站”:

Servlet_第17张图片

tomcat 没启动 


五、Servlet 常用 API

1、HttpServlet

Servlet_第18张图片

(1)init

HttpServlet 实例化指的是 tomcat 首次收到了和该类相关联的请求的时候

tomcat 收到了 /hello 这样的路径的请求,就会调用到 HelloServlet,于是就需要先对 HelloServlet 进行实例化(实例化只进行一次)

后续再收到 /hello ,就不必再实例化了,直接复用之前的 HelloServlet 实例即可

@WebServlet ("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        //可以在这里重写 init 方法
        //插入一些我们自己 "初始化" 相关的逻辑
        System.out.println("init");
    }

我们在原先的代码中,加入一段 init,然后多次刷新页面,

此时就会发现,Init 代码只会在实例化的时候,首次被调用,后续不管怎么触发请求,都不会再被调用了

Servlet 是服务器上的代码,只要服务器不重新启动,init 就不会再执行到


(2)destroy

只要服务器在运行,都可能在使用,当服务器终止的时候,就不使用了

注意:这里的 destroy 能否被执行到,是不确定的

1、如果是直接通过 smart tomcat 的停止按钮,这个操作本质上是通过 tomcat 的 8005 端口主动停止,能够触发 destroy

2、如果是直接杀进程,可能就来不及执行 destroy ,就没了

因此,我们不太推荐使用 destroy ,因为它不是很靠谱


(3)service

每次收到 http 请求,就会触发(路径匹配的请求)

doGet 就是在 service 中调用的


这三个方法,就是 HttpServlet 中给最关键的三个方法

Servlet 的生命周期是怎么回事?

1、开始的时候,执行 init 

2、每次收到请求,执行 service 

3、销毁之前,执行 destroy

接下来,我们写了这么一段代码:

@WebServlet("/method")
public class methodServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        resp.getWriter().write("doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost");
        resp.getWriter().write("doPost");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPut");
        resp.getWriter().write("doPut");
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doDelete");
        resp.getWriter().write("doDelete");
    }
}

当我们在浏览器中运行的时候,会发现,此时发送的是一个 doGet 请求

那么如何构造其它不同种类的请求呢?

1、通过 ajax 

2、通过 postman

我们现在来看一下通过 postman 构造请求:

Servlet_第19张图片

也可以选择通过 ajax 来构造请求

Servlet_第20张图片

注意:这个 html 文件要放在 webapp 目录下 




    
    
    Document


    
    
    

同样的,要注意路径

 Servlet_第21张图片

当然,也可以用绝对路径的写法,在这里,绝对路径是这样写的:

Servlet_第22张图片


 2、HttpServletRequest

HttpServletRequest 表示的是 HTTP 请求

这个对象是 Tomcat 自动构造的,Tomcat 其实是会实现监听端口,接受链接,读取请求,解析请求,构造请求对象等一系列工作

Servlet_第23张图片

query string 是键值对结构,此处就可以通过 getParameter 方法来根据 key 获取到 value

代码示例:

@WebServlet("/showRequest")
public class showRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //这里是设置响应的 content-type,告诉浏览器,响应的 body 里的数据格式是什么样的
        resp.setContentType("text/html");

        //弄一个 StringBuilder ,把这些 api 的结果给拼起来,统一写回到响应中
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("
"); stringBuilder.append(req.getMethod()); stringBuilder.append("
"); stringBuilder.append(req.getRequestURI()); stringBuilder.append("
"); stringBuilder.append(req.getContextPath()); stringBuilder.append("
"); stringBuilder.append(req.getQueryString()); stringBuilder.append("
"); //获取到 header 中所有的键值对 Enumeration headerNames= req.getHeaderNames(); while (headerNames.hasMoreElements()){ String headerName = headerNames.nextElement(); stringBuilder.append(headerName + " " + req.getHeader(headerName)); stringBuilder.append("
"); } resp.getWriter().write(stringBuilder.toString()); } }

3、HttpServletResponse

Servlet_第24张图片

 一个 HTTP 响应中,报头的 key 是可以存在多个重复的

设置的 ContentType 和 字符集,务必要在  write 上面

这是构造重定向响应(302)

重定向:浏览器会自动跳转到指定的新地址

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("https://www.sogou.com");
    }
}

或者这样写,效果和上面的代码效果是相同的

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //resp.sendRedirect("https://www.sogou.com");
        resp.setStatus(302);
        resp.setHeader("Location","https://www.sogou.com");
    }
}

keep-alive:建议 浏览器 和 服务器 之间保持长连接

TCP 是有连接的

短连接:每个连接至进行一次请求和响应的传输

长连接:每个连接可以进行多次请求和响应


 六、前端给后端传参

1、GET ,通过 query string 传递给后端

2、POST ,通过 form 表单的格式

3、POST,通过 json 的格式

1、GET,query string

在前端给后端传两个数字,一个是 studentId,一个是 classId

@WebServlet("/getParameter")
public class getParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //预期浏览器会发一个形如 /getParameter?studentId=10&classId=20 的请求
        //借助 req 里面的 getparameter 方法,就能拿到 query string 中的键值对内容了
        //getparameter得到的是 string 类型的结果
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        resp.setContentType("text/html");
        resp.getWriter().write("studentId = " + studentId + "classId = " + classId);
    }
}

这里的 query string 键值对,会自动被 tomcat 处理成形如 Map 这样的结构,后续就可以随时通过 key 获取 value 了

如果 key 在 query string 中不存在,此时返回值就是 null


2、POST ,form

对于前端是 form 表单这样的数据格式,后端还是使用 getParameter 来获取

form 表单也是键值对,与 query string 的格式一样,只不过这部分内容在 body 中

@WebServlet("/postParameter")
public class PostParameterServlet extends HelloServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        resp.setContentType("text/html");
        resp.getWriter().write("studentId = " + studentId + "classId = " + classId);
    }
}

使用 getParameter 既可以获取到 query String 里面的键值对,也可以获取到 form 表单构造的 body 中的键值对

这个前后端交互的过程,大概可以描述成这样:Servlet_第25张图片


3、POST ,json

json 是一种非常主流的数据格式,也是键值对结构

Servlet_第26张图片

我们可以把 body 按照这个格式来 组织,前端可以通过 ajax 的方式来构造出这个内容,更简单的办法是使用 postman

Servlet_第27张图片

@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HelloServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过这个方法来处理  body 为 json 格式的数据
        //直接把 req 对象里 body 给完整读取出来
        //getInputStream
        //在 流对象 中,读多少个字节,取决于 content-length
        int length = req.getContentLength();
        byte[] buffer = new byte[length];
        
       InputStream inputStream =  req.getInputStream();
       inputStream.read(buffer);
       
       //把这个字节数组构造成 string
        String body = new String(buffer);
        System.out.println("body = " + body);
        resp.getWriter().write(body);
    }
}

 此处打印的结果,就是从 body 中读到的内容

Servlet_第28张图片

postman 构造出一个指定的 POST 请求,body 就是 json 数据

请求到达 tomcat ,tomcat 解析成 req 对象

在 servlet 代码中, req.getInputStream 读取 body 的内容

又把 body 的内容构造成响应结果,返回给浏览器(postman)

这个代码的执行流程,和上面通过 form 表单传参,流程是类似的,只不过传输的数据格式不同

当前通过 json 传递数据,但是服务器这边只是把整个 body 读出,没有按照键值对的方式来处理(还不能根据 key 获取 value)

所以,我们可以使用第三方库 jackson 

通过 maven 来引入第三方库

Servlet_第29张图片

选择好对应得版本之后,将 xml 片段粘贴到 pom.xml 中 

class Student{
    public int studentId;
    public int classId;
}

@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HelloServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //使用 jackson 所涉及到得核心对象
        ObjectMapper objectMapper = new ObjectMapper();
        //readvalue 就是把一个 json 格式得字符串,转换成 java 对象
        Student student = objectMapper.readValue(req.getInputStream(),Student.class);
        System.out.println(student.studentId + "," + student.classId);
    }
}

1、这个代码会从 body 中,读出 json 格式的字符串

2、然后根据第二个参数的类对象,创建出以恶搞 Student 实例

3、再解析上述 json 格式的字符串,处理成 map 键值对结构

4、再遍历所有键值对,看 键 的名字 和 Student 实例的哪个属性名字匹配,就把对应的 value 设置到该属性中

5、返回该 Student 实例


七、、Cookie 和 Session

Cookie 是什么?

浏览器提供的持久化存储数据的机制 

Cookie 从哪里来?

Cookie 从服务器返回给浏览器

服务器代码中,由程序员决定要把什么样的信息保存到客户端这边

通过 HTTP 响应的 Set-Cookie 字段,把键值对写回去即可

Cookie 到哪里去?

Cookie 会在后续浏览器访问服务器的时候带到请求的 header 中,发给服务器

为什么要这么搞?(从服务器来,回到服务器)

服务器不是只给一个客户端提供服务的,同一时刻要处理多个客户端

此时服务器就可以通过 Cookie 中给的值,来识别当前客户端是谁,当前客户端的服务提供到哪个环节了(服务器借助 Cookie 自报家门)

Cookie 保存在哪里?

Cookie 存储在浏览器(客户端)所在主机的硬盘中

浏览器会根据域名来分别存储

Cookie 有一个最典型的应用——标识用户的身份信息

Servlet_第30张图片

Cookie 和 Session 之间的 关联 和 区别

关联:

在网站的登录功能中,需要配合使用

区别:

Cookie 是客户端的存储机制, Session 是服务器的存储机制

Cookie 里面可以存各种键值对,Session 则专门用来保存用户的身份信息

Cookie 完全可以单独使用,不搭配 Session (实现 非登录 场景下)

Session 也可以不搭配 Cookie 使用(手机 app 登录服务器,服务器也需要 Session,此时就没有 Cookie 的概念),Cookie 是和浏览器强相关的

Cookie 是属于 HTTP 协议中的一部分,Session 则可以和 Cookie 无关


八、模拟登录的代码

Servlet_第31张图片

这个例子中涉及到两个页面:

1、登录页面

2、主页面

涉及到两个 servlet :

1、处理登录的 Loginservlet ,判定用户名密码

2、构造主页面的 Indexservlet 

1、编写登录页面

2、编写 LoginServlet 处理登录请求

 

所谓的会话,是一个键值对 

key 是 sessionId ,value 是一个 HttpSession 对象

每个客户端登录的时候,都有这样的一个键值对(会话),服务器要管理多个这样的对话

服务器可以弄一个哈希表,把这些对话组织起来

getSession(true) 就是判定当前请求,是否已经有对应的会话了(拿着请求中的 Cookie 里的 SessionId 查一下 哈希表)

如果 SessionId 不存在,或者没查到,就创建新的会话并插入到哈希表中,如果查到了,就返回查到的结果

创建会话过程:

1、构造一个 HttpSession 对象

2、构造唯一的 sessionId

3、把这个键值对插入到哈希表

4、把 SessionId 设置到 响应报文中 Set-Cookie 字段中

HttpSession 对象,自己也是一个键值对

可以通过 setAttribute 和 getAttribute 来存取键值对

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //验证用户名密码是否正确
        //正常情况下,用户名密码使用数据库保存
        //此处直接写死
        //此处,用户名: zhangsan 和 lisi
        //密码:123

        if (!username.equals("zhangsan") && !username.equals("lisi")) {
            //登录失败
            //直接重定向到登录页面
            System.out.println("登录失败,用户名错误");
            resp.sendRedirect("login.html");
            return;
        }
        if (!password.equals("123")){
            //登录失败
            System.out.println("登录失败,密码错误");
            resp.sendRedirect("login.html");
            return;
        }
        //登录成功
        //1、创建一个会话
        HttpSession session = req.getSession(true);
        //2、把当前的用户名保存到对话中,此处的 HttpSession 可以当成一个 Map 使用
        session.setAttribute("username",username);
        //3、重定向到主页
        resp.sendRedirect("index");
    }
}

会话这里,服务器是如何组织的?

Servlet_第32张图片

3、编写 IndexServlet 生成主页

 

此处可以这样取,是因为前面的登录操作已经存过了

HttpSession value 的类型是 Object ,需要手动强转为 String(设定 Object 意思就是你存各种类型都行)

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    //通过重定向,浏览器发送的是 Get 请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //先判定用户的登录状态
        //如果用户还没有登录,要求先登录
        //已经登陆了,则根据会话中的用户名,来显示到页面上
        //这个操作不会触发会话的创建
        HttpSession session = req.getSession(false);
        if (session == null){
            //未登录状态
            System.out.println("用户未登录");
            resp.sendRedirect("login.html");
            return;
        }
        //已经登陆了
        String username =(String) session.getAttribute("username");
        //构造页面
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write(" 欢迎 " + username + " 回来!");
    }
}

你可能感兴趣的:(Java,EE,servlet,tomcat,maven,java-ee,后端)