Servelt&&JSP进阶
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 三大作用域对象
- HttpServletRequest 请求对象-瞬时对象;
- HttpSession 用户会话对象- 用户第一次请求访问开始创建,然后30min没有用到就会被销毁;
- 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进阶的更多相关文章
- JSP进阶 之 SimpleTagSupport 开发自定义标签
绝大部分 Java 领域的 MVC 框架,例如 Struts.Spring MVC.JSF 等,主要由两部分组成:控制器组件和视图组件.其中视图组件主要由大量功能丰富的标签库充当.对于大部分开发者而言 ...
- jsp进阶
Jsp,前段的数据读取到后端 获取前段输入框数据 request.getParameter(前段输入框的name值) Request.代表转发,(代码在服务器内部执行的一次性请求,url地址不会发生改 ...
- 9.JSP进阶
1.JSP内置对象 JSP容器在_jspService()方法中声明并初始化9个内置对象. 名称 作用 接口/类 out 客户端打开的输出流 javax.servlet.jsp.JspWriter 接 ...
- 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 ...
- JSP概述
一.JSP页面本质上时一个Servlet,然而,用JSP开发比使用Servlet更容易,主要有两个原因,首先不必编译Servlet,其次JSP页面是一个以.jsp为扩展名的文本文件,可以使用任何编辑器 ...
- JavaWeb学习记录(十九)——jstl自定义标签之简单标签
一.简单标签共定义了5个方法: setJspContext方法 setParent和getParent方法 setJspBody方法 doTag方法 二.方法介绍 osetJspContext方法 用 ...
- Java并发简介
年轻的时候学会了“使用”Servlet后,感觉自己什么都会做了,之后就不停的写所谓的业务逻辑,框架(这里说的不是structs,spring等,就是说servlet)给人们屏蔽了很多复杂性(更别说构建 ...
- Maven 初学+http://mvnrepository.com/
了解 maven是一款服务于java平台的自动化构建工具(项目管理工具) 构建:全方位.多角度.深层次地建立 项目构建是一个项目从:源代码.编译.测试.打包.部署.运行的过程 用来解决团队开发遇到的问 ...
- 【Web】CSS中的浮动float
CSS中的float 文章目录 CSS中的float 1.float浮动属性 2.float文字环绕图片 3.float浮动的真正原因以及副作用分析 4.清除浮动的四种解决方法 5.实际应用 导航效果 ...
随机推荐
- ES2021 新特性!
大家好,我是前端队长Daotin,想要获取更多前端精彩内容,关注我(全网同名),解锁前端成长新姿势. 以下正文: 2021 年 6 月 22 日,第 121 届 Ecma 国际(Ecma Intern ...
- CentOS-Docker搭建VeryNginx
下载镜像 $ docker pull camil/verynginx $ cd /home GIT克隆(yum install git -y) $ git clone https://github.c ...
- redis-list实现
Redis 数据结构---链表 Redis的list底层实现使用的不是数组而是链表的数据结构 叫listnode 是一个双向链表 ListNode{ Struct listNode *prev / ...
- 使用命令行操作MySQL 及 语法
在使用之前先要确保服务中的MySQL 已启动,否则会报错:ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061 ...
- gitlab git 安装
1.配置yum源 vim /etc/yum.repos.d/gitlab-ce.repo [gitlab-ce] name=Gitlab CE Repository baseurl=https://m ...
- BUU mrctf shit
吐槽:去年没写出的题,现在终于可以上手了,昂哥nb 动调发现直接卡着不动了,怀疑是反调试,果然有好几处反调试 这里选择就不先nop了,先让程序跑起来,然后attach,在输入函数下面下个断点,atta ...
- SpEL表达式总结(转)
前言 SpEL(Spring Expression Language),即Spring表达式语言,是比JSP的EL更强大的一种表达式语言.为什么要总结SpEL,因为它可以在运行时查询和操作数据,尤其是 ...
- 选择适合入门的自动化测试框架TestNG 基于Java语言的入门选择之一
对于测试工程师新手来说,最痛苦的莫过于入门,其实只要入门3个月左右,对于自动化测试,所有的测试工程师除了喜爱,就是更爱.自动化测试工作,是从根本上解放人性,不用重复去完成鼠标的点点点,例如以下测试常常 ...
- 锐捷RG-S2951G-EV3 ACL 禁止端口
(config)ip access-list extended 199 (config)10 deny tcp any any eq 2425 (config)20 deny udp any any ...
- python import 导入两个模块同时有同一名称的方法如何调用 ?
from moudule import *(这种方法不推荐) 一般不推荐使用"from 模块 import"这种语法导入指定模块内的所有成员,因为它存在潜在的风险. 比如同时导入 ...