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 两个帖子
标签:&&,resp,req,JSP,Servelt,Cookie,import,servlet,javax 来源: https://www.cnblogs.com/it-bt/p/14350624.html