Servlet与JSP进阶

来自mkw的视频课程的总结

1.前言

内容包括 掌握Java Web核心特性,Servlet核心对象以及JSP九大内置对象。主要有以下的内容:

  • 请求结构 && 响应结构
  • 请求转发重定向
  • Cookie && Session
  • ServletContext 与三大作用域
  • 请求响应中文乱码问题解决
  • Web.xml常用配置
  • JSP九大内置对象
  • web应用程序打包和发布

2. 请求结构

请求行,请求头,请求体

请求头包括Accept-Language:zh-CN(国际化),Content-Type等 浏览器的辅助信息。

对于get请求,请求的内容一般放在 query String Parameters,在POST中放在From Data中,此外,格式内容都一样

UserAgent适用于不同终端的开发

3.响应结构

状态码:200 404 500 403(服务器拒绝访问) 301/302 400(无效请求)

Content-Type明确网页解析响应体的格式,一般为 text/html, plain是原文 application/x-msdownload

4.请求转发与响应重定向

从一个页面自动跳转到另一个页面

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("用户登陆成功!");
//实现了请求转发的功能
req.getRequestDispatcher("/direct/index").forward(req,resp); // 响应重定向 需要增加 contextPath
resp.sendRedirect("/Servlet_advanced_war_exploded/direct/index");
}

二者的区别,表面上看是 最终的URL不同,请求转发的URL是最初的 /direct/check,而响应重定向是 /direct/index,内容都是 index的内容

二者原理的区别:

请求转发:Tomcat服务器内部,Servlet1处理后,在req.getRequestDispatched().forward()语句下,将原请求原封不动转交给Servlet2。

响应重定向:浏览器跳转,产生两次请求,语句是response.sendRedirect(),这里响应1不是html网页,而是告诉浏览器再发送一个请求给Servlet2的地址。

4.1 设置请求自定义属性

  • 允许创建自定义属性
  • 设置请求属性: request.setAttribute(属性名,属性值)
  • 获取请求属性: request.getAttribute(属性名,属性值)

5.Cookie

​ Cookie的引文原意是“点心”,它是在客户端访问Web服务器时,服务器在客户端硬盘上存放的信息,好像是服务器发送给客户的“点心”。服务器可以根据Cookie来跟踪客户状态(之前是否已经登录),这对于需要区别客户的场合(如电子商务)特别有用。

​ 当客户端首次请求访问服务器时,服务器先在客户端存放包含该客户的相关信息的Cookie,以后客户端每次请求访问服务器时,都会在HTTP请求数据中包含Cookie,服务器解析HTTP请求中的Cookie,就能由此获得关于客户的相关信息。

Cookie是浏览器保存本地,记录用户登录状态和资料的文本,具有时效性,默认是浏览器关闭Cookie就会被清空,可以用setMaxAge()设置。Cookie内容会伴随请求发送给Tomcat,常用的方法有:

LoginServlet.java

@WebServlet("/cookies/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("用户登录成功");
Cookie cookie = new Cookie("user","admin");
cookie.setMaxAge(60*60*4*7);
resp.addCookie(cookie);
resp.getWriter().println("login success");
}
}

IndexServlet.java

@WebServlet("/cookies/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cs = req.getCookies();
String user = null; //防止空指针异常 for(Cookie c:cs) {
if(c.getName().equals("user")) {
user = c.getValue();
break;
}
System.out.println(c.getName() + ": " + c.getValue());
} if(user == null) {
resp.getWriter().println("User no login in");
} else {
resp.getWriter().println("User:" + user);
}
}
}

6.Session

  • Session(用户会话)用于保存与“浏览器窗口”(并不是实际的浏览器窗口)对应的数据;
  • 存储在Tomcat服务器内存中,具有时效性(默认30min没有用到就会被销毁);
  • Session通过浏览器Cookie的SessionID值针对性提取用户数据;

Cookie中保存的sessionID将 cookie和对应的session连接在一起,这里有一个问题需要清楚:

Cookie的生命周期是和浏览器绑定在一起的,关闭浏览器后Cookie(包含sessionID)就会被清除,而一个session的在Tomcat的生命周期是 30min,二者不矛盾。下面内容引用自请叫我丁木西

那么为什么当我们关闭浏览器后,就再也访问不到之前的session了呢?其实之前的Session一直都在服务器端,而当我们关闭浏览器时,此时的Cookie是存在于浏览器的进程中的,当浏览器关闭时,Cookie也就不存在了。其实Cookie有两种:

一种是存在于浏览器的进程中; 一种是存在于硬盘上。

session的Cookie是存在于浏览器的进程中,那么这种Cookie我们称为会话Cookie,当我们重新打开浏览器窗口时,之前的Cookie中存放的Sessionid已经不存在了,此时服务器从tpServletRequest对象中没有检查到sessionid,服务器会再发送一个新的存有Sessionid的Cookie到客户端的浏览器中,此时对应的是一个新的会话,而服务器上原先的session等到它的默认时间到之后,便会自动销毁

附加

当在同一个浏览器中同时打开多个标签,发送同一个请求或不同的请求,仍是同一个session;

当不在同一个窗口中打开相同的浏览器时,发送请求,仍是同一个session; 这个不太好理解

当使用不同的浏览器时,发送请求,即使发送相同的请求,是不同的session;

当把当前某个浏览器的窗口全关闭,再打开,发起相同的请求时,是不同的session。

Code demo

SessionLoginServlet

package com.imooc.servlet.session;

import com.sun.xml.internal.ws.addressing.WsaActionUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/session/login")
public class SessionLoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("登录成功");
HttpSession session = req.getSession();
String sessionId = session.getId();
System.out.println(sessionId);
session.setAttribute("name","张三");
req.getRequestDispatcher("/session/index").forward(req,resp); //请求转发到 "/session/index"
}
}

SessionIndexServlet.java

package com.imooc.servlet.session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; @WebServlet("/session/index")
public class SessionIndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
String sessionId = session.getId();
System.out.println(sessionId);
String name = (String) session.getAttribute("name");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println("这是首页,当前用户" + name);
}
}

7.ServletContext与三大作用域对象

7.1 ServletContext

  • ServletContext(Servlet上下文对象),是Web应用全局对象

  • 一个Web应用只会创建一个ServletContext对象

  • ServletContext随着Web应用启动而自动创建

ServletContext适合整个应用/网站的全局信息,在每一个页面都有的,比如页脚的网站的备案信息等。

Code Demo

ContextInitServlet.java

package com.imooc.servlet.ServletContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet("/context/init")
public class ContextInitServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = req.getServletContext();
context.setAttribute("copyright","@ 2020 www.imooc.com 京");
context.setAttribute("title","慕课网-程序员的梦工厂");
resp.getWriter().println("Init Success");
}
}

ServletDefaultServlet.java

package com.imooc.servlet.ServletContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet("/context/default")
public class ServletDefaultServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = req.getServletContext();
String copyright = (String) context.getAttribute("copyright");
String title = context.getAttribute("title").toString();
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println("<h1>" + title + "</h1>" + copyright);
}
}

与前面不同,当先后访问两个页面之后关闭浏览器,再打开新浏览器直接访问 "/context/default"。结果不变,这是因为ServletContext是应用全局对象,只要应用启动初始化后,就一直存在。

7.2 Java-Web 三大作用域对象

  1. HttpServletRequest 请求对象-瞬时对象;
  2. HttpSession 用户会话对象- 用户第一次请求访问开始创建,然后30min没有用到就会被销毁;
  3. ServletContext web应用全局对象,web启动后就被创建,生命周期最久。

8.Web请求&响应中文乱码

Tomcat默认使用字符集ISO-8859-1,属于西欧字符集,解决乱码即用UTF-8替换即可,在Servlet中,请求与响应都需要设置UTF-8字符集

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body> <form action="/Servlet_advanced_war_exploded/charset/process" method="post">
姓名:<input name="ename">
地址:<input name="address">
<input type="submit" value="提交">
</form> </body>
</html>
package com.imooc.servlet.charset;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet("/charset/process")
public class CharsetServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//方法2 req.setCharacterEncoding("UTF-8");
String ename = req.getParameter("ename");
String address = req.getParameter("address");
//方法1
// String utf8ename = new String(ename.getBytes("iso-8859-1"), "utf-8")
System.out.println(ename + ":" + address);
}
}

控制台产生:???:???é??,解决方案是 单个语句转换可以使用方法1,全局设置可以使用方法2

get请求乱码解决

在 Tomcat version >=8版本不存在这个问题,但是 低版本可以修改 Tomcat安装目录 conf/server.xml 的第69行

添加 URIEncoding="UTF-8" ,即修改成

解决

9.Web.xml常用配置

Web.xml是Java Web项目最重要的配置文件

9.1 默认首页

在默认创建项目后的Web.xml中,会存在如下代码:

<welcom-first>index.html</welcom-first>
<welcom-first>index.htm</welcom-first>
<welcom-first>index.jsp</welcom-first>
<welcom-first>default.html</welcom-first>
<welcom-first>index.htm</welcom-first>
<welcom-first>index.jsp</welcom-first>

功能是 如果在Web目录下有任何一个上述的文件,都会成为其默认的首页,可以用户自定义,同时定义了二级目录中默认的页面

9.2 使用WebServlet通配符

某些URL前缀相同的请求都会被拦截

package com.imooc.servlet.pattern;

import javax.servlet.ServletException;
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 PatternServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String url = req.getRequestURL().toString();
System.out.println(url);
String id = url.substring(url.lastIndexOf("/") + 1);
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println(id); if(id.equals("1")) {
out.println("张三");
}else if(id.equals("2")) {
out.println("李四");
}else {
out.println("其他员工");
}
}
}

Web.xml 添加如下信息:

    <servlet>
<servlet-name>patternServlet</servlet-name>
<servlet-class>com.imooc.servlet.pattern.PatternServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>patternServlet</servlet-name>
<url-pattern>/pattern/*</url-pattern>
</servlet-mapping>

9.4 全局参数的配置

在Web.xml中可以定义全局参数

 <context-param>
<param-name>copyright</param-name>
<param-value>@2021 imooc.com 京</param-value>
</context-param>
<context-param>
<param-name>title</param-name>
<param-value>慕课网-程序员的梦工厂</param-value>
</context-param>

在Java中获取

String copyright = context.getInitParameter("copyright");

9.3 404 500页面设置

在web项目下新建 error目录,然后新建 404.html和 500.html。在Web.xml上添加

<error-page>
<error-code>404</error-code>
<location>/error/404.html</location>
</error-page> <error-page>
<error-code>500</error-code>
<location>/error/500.html</location>
</error-page>

如此设置是避免程序错误产生的系统报错信息直接显示在页面上,泄露一些程序的逻辑信息,提高安全性。

10.JSP九大内置对象

就是不同对象的简略写法。

11.Java-Web打包与发布

  • Java Web应用采用war包进行发布
  • 发布路径: {Tomcat_Home}/webapps
  • Eclipse支持war包导出

这里发现在 server.xml中无法设置 端口号和 path 的默认,找不到视频中要修改的东西。

IDEA打包war 参考小白马上飞Tanyiqu-bili 两个帖子

Servelt&&JSP进阶的更多相关文章

  1. JSP进阶 之 SimpleTagSupport 开发自定义标签

    绝大部分 Java 领域的 MVC 框架,例如 Struts.Spring MVC.JSF 等,主要由两部分组成:控制器组件和视图组件.其中视图组件主要由大量功能丰富的标签库充当.对于大部分开发者而言 ...

  2. jsp进阶

    Jsp,前段的数据读取到后端 获取前段输入框数据 request.getParameter(前段输入框的name值) Request.代表转发,(代码在服务器内部执行的一次性请求,url地址不会发生改 ...

  3. 9.JSP进阶

    1.JSP内置对象 JSP容器在_jspService()方法中声明并初始化9个内置对象. 名称 作用 接口/类 out 客户端打开的输出流 javax.servlet.jsp.JspWriter 接 ...

  4. tomcat各版本和jsp、jstl、servlet的依赖关系(转)

    Servlet / JSP / Tomcat  Version  Servlet/ JSP    Tomcat  2.5/2.1 6.0.18 2.4/2.0 5.5.27 2.3/1.2 4.1.3 ...

  5. JSP概述

    一.JSP页面本质上时一个Servlet,然而,用JSP开发比使用Servlet更容易,主要有两个原因,首先不必编译Servlet,其次JSP页面是一个以.jsp为扩展名的文本文件,可以使用任何编辑器 ...

  6. JavaWeb学习记录(十九)——jstl自定义标签之简单标签

    一.简单标签共定义了5个方法: setJspContext方法 setParent和getParent方法 setJspBody方法 doTag方法 二.方法介绍 osetJspContext方法 用 ...

  7. Java并发简介

    年轻的时候学会了“使用”Servlet后,感觉自己什么都会做了,之后就不停的写所谓的业务逻辑,框架(这里说的不是structs,spring等,就是说servlet)给人们屏蔽了很多复杂性(更别说构建 ...

  8. Maven 初学+http://mvnrepository.com/

    了解 maven是一款服务于java平台的自动化构建工具(项目管理工具) 构建:全方位.多角度.深层次地建立 项目构建是一个项目从:源代码.编译.测试.打包.部署.运行的过程 用来解决团队开发遇到的问 ...

  9. 【Web】CSS中的浮动float

    CSS中的float 文章目录 CSS中的float 1.float浮动属性 2.float文字环绕图片 3.float浮动的真正原因以及副作用分析 4.清除浮动的四种解决方法 5.实际应用 导航效果 ...

随机推荐

  1. 解决Windows Server 2012 在VMware ESXi中经常自动断网问题

    最近一些开发人员反映他们使用的 Windows server2012 R2 虚拟机过段时间就远程连接不上了,ping也不通(已关闭防火墙),我们登录ESXi发现,Windows Server 的网络图 ...

  2. 其他:IDEA插件无法安装——网络代理设置

    1.网络代理设置 IDEA配置代理,是在File-> Setting-> plugins中设置 查看自己主机的IP地址 文章转载至:https://www.jianshu.com/p/62 ...

  3. Java线程池中的核心线程是如何被重复利用的?

    真的!讲得太清楚了!https://blog.csdn.net/MingHuang2017/article/details/79571529 真的是解惑了 本文所说的"核心线程". ...

  4. 使用xcodeproj 动态插入第三方代码

    # 为什么这么做? 现在有这么一个使用场景,基线能生成项目A,项目B,项目C...如果只有项目A中使用SDK_A,其他项目都不使用,这时候就需要对基线进行差分,只有当我切换到项目A时,才插入SDK_A ...

  5. WPF教程四:字段、属性、依赖项属性的演变过程

    这个章节主要讲解属性是什么,为什么会演变出依赖项属性,依赖属性的优势是什么.以及如何更好的使用属性和依赖项属性. 一.属性 属性是什么. 翻了好几本C#的书和微软的文档,我觉得对属性讲解比较好理解的就 ...

  6. Adaptive AUTOSAR 学习笔记 1 - Overview

    缩写 AP: AUTOSAR Adaptive Platform CP: AUTOSAR Classic Platform AA: Adaptive Application ARA: AUTOSAR ...

  7. LOJ528 「LibreOJ β Round #4」求和

    LOJ528 「LibreOJ β Round #4」求和 先按照最常规的思路推一波: \[\begin{aligned} &\sum_{i=1}^n\sum_{j=1}^m\mu^2(\gc ...

  8. python 读取 写入txt文件

    filename = 'pi_digits.txt' with open(filename) as f:#默认以只读方式打开文件 lines = f.readlines()#读取所有行,结果为列表,每 ...

  9. ESP8266 NodeMCU小白手把手入门(实操篇)以土壤湿度和DHT传感器为例讲解读取传感器的值

    物联网使得现实世界中的实体和数字世界比以往任何时候都更紧密地联系在一起.NodeMCU作为其中的一个重要设备,作用之一就是与传感器相连以实现万物互联通讯.这篇关于NodeMCU的实操篇以土壤湿度传感器 ...

  10. 解决 Github 打不开或打开很慢的问题

    解决 Github 打不开或打开很慢的问题 方法一 一.确定 github 网站的 ip 打开网址:http://github.com.ipaddress.com/ 192.30.253.112 gi ...