JavaWeb学习笔记
一、Servlet介绍
概念:
Servlet是运行在Java服务器端的程序,用于接收和响应来自客户端基于HTTP协议的请求。
实现:
如果想要实现Servlet的功能,可以通过实现Servlet接口或者继承他的实现类。
核心方法:
service(),任何客户端的请求都会经过该方法。
二、.请求对象
1.请求对象常用的方法
返回值 | 方法名 | 说明 |
---|---|---|
String | getContexPath() | 获取虚拟目录名称 |
String | getServletPath() | 获取Servlet映射路径 |
String | getPemoteAddr() | 获取访问者IP地址 |
String | getQueryString() | 获取请求的消息数据 |
String | getRequestURI() | 获取统一资源标识符 |
String | getRequestURL() | 获取统一资源定位符 |
@WebServlet("/login")
public class demo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 请求路径为:http://localhost:8080/basic_web/login?usern&password=123
// String getContexPath() 获取虚拟目录名称 //发布项目时配置的虚拟名称 /basic_web
String contextPath = req.getContextPath();
System.out.println(contextPath);
// String getServletPath() 获取Servlet映射路径 //@WebServlet("/login") /login
String servletPath = req.getServletPath();
System.out.println(servletPath);
// String getRemoteAddr()获取访问者IP地址 0:0:0:0:0:0:0:1
String remoteAddr = req.getRemoteAddr();
System.out.println(remoteAddr);
// String getQueryString() 获取请求的消息数据 //请求的附带的参数数据 usern&password=123
String queryString = req.getQueryString();
System.out.println(queryString);
// String getRequestURI() 获取统一资源标识符 //端口号后边输入的内容 /basic_web/login
String requestURI = req.getRequestURI();
System.out.println(requestURI);
// String getRequestURL() 获取统一资源定位符 //路径全称 http://localhost:8080/basic_web/login
StringBuffer requestURL = req.getRequestURL();
System.out.println(requestURL);
}
}
2、获取请求头信息
返回值 | 方法名 | 说明 |
---|---|---|
String | getHeader(String name) | 根据请求头名称获取一个值 |
Enumeration | getHeaders(String name) | 根据请求头名称获取多个值 |
Enumeration | getHeaderNames() | 获取所有请求头名称 |
@WebServlet("/login2")
public class demo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// StringgetHeader(String name)根据请求头名称获取一个值 keep-alive
String connection = req.getHeader("connection");
System.out.println(connection);
System.out.println("----------");
// Enumeration<String>getHeaders(String name)根据请求头名称获取多个值 gzip, deflate, br
Enumeration<String> encoding = req.getHeaders("accept-encoding");
while (encoding.hasMoreElements()) {
String s = encoding.nextElement();
System.out.println(s);
}
System.out.println("----------");
// Enumeration<String>getHeaderNames()获取所有请求头名称
//host
//connection
//cache-control
//upgrade-insecure-requests
//user-agent
//accept
//sec-fetch-site
//sec-fetch-mode
//sec-fetch-user
//sec-fetch-dest
//accept-encoding
//accept-language
//cookie
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String s = headerNames.nextElement();
System.out.println(s);
}
}
}
3、获取请求参数信息
返回值 | 方法名 | 说明 |
---|---|---|
String | getParameter(String name) | 根据名称获取数据 |
String[] | getParameterValues(String name) | 根据名称获取所有数据 |
Enumeration | getParameterNames() | 获取所有的名称 |
Map<String,String[]> | getParameterMap() | 获取所有参数的键值对 |
@WebServlet("/login3")
public class demo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String getParameter(String name)根据名称获取数据
String username = req.getParameter("username");
System.out.println(username);
String password = req.getParameter("password");
System.out.println(password);
System.out.println("-------");
// String[] getParameterValues(String name)根据名称获取所有数据 //如有多选框就需要获取多个值
String[] hobbies = req.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
System.out.println("--------");
// Enumeration<String> getParameterNames()获取所有的名称
Enumeration<String> parameterNames = req.getParameterNames();
while (parameterNames.hasMoreElements()) {
String element = parameterNames.nextElement();
System.out.println(element);
}
System.out.println("---------");
// Map<String,String[]> getParameterMap()获取所有参数的键值对 名称与值
Map<String, String[]> parameterMap = req.getParameterMap();
for (String key : parameterMap.keySet()) {
for (String value : parameterMap.get(key)) {
System.out.println(key + ":" + value);
}
}
}
}
4、中文乱码问题
原因:
前后端页面请求数据的编码格式不一致导致,可在后端用代码对请求编码进行修改,修改成与前端页面请求编码格式一致即可。
- GET方式:
- 没有乱码问题,在Tomcat8版本后已经解决。
- POST方式:
- 有乱码问题,可以通过setCharacterEncoding()方法来解决。
req.setCharacterEncoding("UTF-8");
5、请求转发
介绍:
客户端的一次请求到达后,发现需要借助其他Servlet来实现功能。
特点:
- 浏览器地址栏不变
- 域对象中的数据不丢失
- 负责转发的Servlet转发前后的响应会丢失
- 由转发的目的地来响应客户端
返回值 | 方法名 | 说明 |
---|---|---|
RequestDispather | getRequestDispatcher(String name) | 获取请求调度对象 |
void | forward(ServletRequest req,ServletResponse resp) | 实现转发 |
req.getRequestDispatcher(转发地址).forward(req,resp);
6、请求包含
介绍:
可以合并其他Servlet中的功能一起响应给客户端
特点:
-
浏览器地址栏不变
-
域对象中的数据不丢失
-
被包含的Servlet响应头会丢失
返回值 方法名 说明 RequestDispather getRequestDispatcher(String name) 获取请求调度对象 void include(ServletRequest req,ServletResponse resp) 实现包含
三、响应对象
响应:
回馈结果。服务器端给客户端反馈结果。
响应对象:
在项目中用于发送响应的对象。
1、响应编码格式:
用于设置响应对象返回数据到浏览器的编码格式,解决浏览器中文乱码问题。
resp.setContentType("text/html;charset=UTF-8");
2、常见状态码
状态码 | 说明 |
---|---|
200 | 成功 |
302 | 重定向 |
304 | 请求资源未改变。使用缓存 |
400 | 请求错误,常见于请求参数错误 |
404 | 请求资源找不到,常见于路径找不到具体的资源 |
405 | 请求方式不支持 |
500 | 服务器错误 |
3、设置缓存
缓存: 对于不经常变化的数据,我们可以设置合理的缓存时间,以避免浏览器频繁请求服务器,一次来提高效率。
setDateHeader(String name,long time)
设置消息头添加缓存时间
4、定时刷新
定时刷新: 过了指定时间后,页面自动进行跳转。
setHeader(String s,String s1)
设置消息头的刷新时间
setHeader("Refresh","3;URL=跳转路径")
; 设置响应消息头,响应时间,跳转路径
5、请求重定向
请求重定向: 客户端的一次请求到达后,发现需要借助其他Servlet来实现功能。
特点: 浏览器地址栏会发生改变,两次请求,请求域对象中共享数据会丢失,可以重定向到其他服务器。
重定向实现原理:
-
设置响应状态码为302.
resp.setStatus(302);
-
设置响应的资源路径,通过响应消息头location来指定.
resp.setHeader("location","重定向资源路径");
3.响应对象重定向方法:
sendRedirect(String name); 设置重定向
四、四大作用域
域对象 | 功能 | 作用 |
---|---|---|
ServletContext:contextApplication | 应用域 | 在整个应用之间实现数据共享 |
HttpSession | 会话域 | 在当前会话范围之间实现数据共享 |
ServletRequest | 请求域 | 在当前的请求或请求转发之间实现数据共享 |
PageContext | 页面域 | Jsp都有,可操作其他三个域对象中的属性,还可获取其他八大隐式对象。每一个Jsp页面有一个PageContext对象 |
五、Cookie会话
会话 浏览器和服务器之间的多次请求和响应。
会话过程中所产生的一些数据(如:用户名密码,购物车等),可以通过会话技术保存。
Cookie: 客户端会话管理技术
把要共享的数据保存在客户端。每次请求时,把会话信息带到服务器,从而实现多次请求共享数据!
作用: 可以保存客户端访问网站的相关内容,从而保证每次访问时先从本地缓存中获取,以此提高效率。
方法名 | 说明 |
---|---|
Cookie(String name,String value) | 构造方法创建对象 |
属性对应的set和get方法 | 赋值和获取值 |
范返回值 | 方法名 | 说明 |
---|---|---|
void | addCookie(Cookie cookie) | HttpServletResponse向客户端添加Cookie |
Cookie[] | getCookies() | HttpServletRequest获取所有的Cookie |
注意事项
-
数量限制:每个网站最多只能有20个Cookie,且大小不能超过4kb,所有网站Cookie总数不能超过300个。
-
名称限制:只能包含字母数字,不支持中文。
-
存活时间限制:setMaxAge()方法接收数字。
负整数:当前会话有效,浏览器关闭则清除。
0:立即清除。
正整数:以秒为单位设置存活时间。
-
路径限制:取第一次访问的资源路径前缀,只要以这个前缀为开头(包括子级路径),都能获取到Cookie。
设置路径:setPath(String s)
六、Session会话技术
HttpSession: 服务端会话管理技术
本质也是采用客户端会话管理技术,只不过在客户端保存的是一个特殊标识,而共享的数据保存在服务端的内存对象中。
每次请求时,都会将特殊标识带到服务端,根据标识找到对应内存空间从而实现数据共享。
Session也是四大域对象之一的会话域对象。
返回值 方法名 说明 void setAttribute(String name,Object value) 设置共享数据 Object getAttribute(String name) 获取共享数据 void removeAttribute(String name) 移除共享数据 String getId() 获取唯一标识符 void Invalidate() 让session立即失效 返回值 方法名 说明 HttpSession getSession() 获取HttpSession对象 HttpSession getSession(boolean create) 获取HttpSession对象,未获取到是否自动创建,默认为true 注意细节
-
浏览器禁用Cookie
方式一:通过提示信息告知用户,大部分网站采用的解决方式(推荐)
方式二:访问时拼接jsessionid标识,通过encodeURL()方法重写地址(了解)
-
钝化和活化
钝化:序列化。把长时间不用还没到过期时间的HttpSession进行序列化,写到磁盘文件中。
活化:正常状态。与钝化相反的状态
-
何时钝化
第一种情况:当访问量很大时,服务器会根据getLastAccessTime来进行排序,对长时间不用但没过期的HttpSession进行序列化。
第二种情况:当服务器进行重启的时候,为了保持客户HttpSession中的数据,也要对其进行序列化。
-
七、EL表达式
EL: 表达式语言
作用: 在JSP页面中获取数据,让我们的JSP脱离Java代码块和JSP表达式。
语法:${ }
- EL表达式能够获取四大域对象的数据,根据名称从小到大在域对象中查找。
- 还可以获取JSP其他八大隐式对象,并调用对象中的方法。
EL表达式隐式对象: 十一个
pageContext:能够获取四大域对象,获取JSP其他八大隐式对象,并调用对象中的方法
applicationScope:操作应用域对象数据
sessionScope:操作会话域对象数据
requestScope:操作请求域对象数据
pageScope:操作页面域对象数据
header:获取请求头数据
headerValues:获取请求头数据(多个值)
param:获取请求参数数据
paramValues:获取请求参数数据(多个值)
initParam:获取全局初始化参数数据
cookie:获取Cookie对象
八、JSTL:JSP标准标签库
开发人员可以使用提供的标签库在JSP页面中取代Java代码,从而提高程序的可读性,降低程序维护难度。
组成 | 作用 | 说明 |
---|---|---|
core | 核心标签库 | 通用的逻辑处理 |
fmt | 国际化 | 不同地域显示不同语言 |
functions | EL函数 | EL表达式可以使用的方法 |
sql | 操作数据库 | 了解 |
xml | 操作XML | 了解 |
JSTL核心标签库
名称 | 功能 | 属性 | 作用 |
---|---|---|---|
<标签库:if> | 流程控制 | 核心标签库 | 用于条件判断 |
<标签库:choose><标签库:when><标签库:otherwise> | 流程控制 | 核心标签库 | 用于多条件判断 |
<标签库:forEach> | 迭代遍历 | 核心标签库 | 用于循环遍历 |
JSP页面条件判断示例代码:
JSP页面循环遍历示例代码: items是获取到的集合名称,var表示起个别名
九、Filter过滤器
介绍: 在程序中访问服务器资源时,当一个请求到来时,服务器首先判断是否有过滤器与请求资源相关联,如果有,则过滤器进行拦截,完成特定的功能后在由过滤器决定是否转发给请求资源,如果没有关联则直接请求资源即可。响应也是类似。
使用场景: 一般用于登录验证,统一编码处理,敏感字符过滤等
Filter是一个接口,想实现过滤器的功能,必须实现该接口。
核心方法:
返回值 | 方法名 | 作用 |
---|---|---|
void | init(FilterConfig config) | 初始化方法 |
void | doFilter(ServletRequest request,ServletResponse response,FilterChain chain) | 对请求资源和响应资源进行拦截过滤 |
void | destroy() | 销毁方法 |
FilterChain介绍
是一个接口,代表过滤器链对象,由Servlet容器提供实现类对象,直接使用即可。
过滤器可以定义多个,就可以组成过滤器链。
核心方法
返回值 | 方法名 | 说明 |
---|---|---|
void | doFilter(ServletRequest request,ServletResponse response) | 放行方法 |
如果有多个过滤器,则该方法的作用是从第一个过滤器中放行到下一个过滤器,以此内推,直到到达最终访问资源。
如果只有一个过滤器,放行时,就会直接到达最终访问资源
//注解拦截所有请求响应的资源 /*
@WebFilter("/*")
public class Filter01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("这里是第一个过滤器");
servletResponse.setContentType("text/html,charset=utf-8"); //过滤器控制的内容
filterChain.doFilter(servletRequest,servletResponse); //放行
}
@Override
public void destroy() {
}
}
过滤器配置方式:如果是注解方式配置多个过滤器则执行顺序和类名字符排序有关!
FilterConfig方法
介绍:FilterConfig是一个接口,代表过滤器的配置对象,可以加载一些初始化参数。
返回值 | 方法名 | 作用 |
---|---|---|
String | getFilter() | 获取过滤器名称 |
String | getInitParameter(String key) | 根据key获取值 |
Enumeration | getInitParameterNames() | 获取所有参数的名称 |
ServletContext | getServletContext() | 获取应用域对象 |
过滤器的五种拦截行为
十、Listener监听器
**观察者设计模式:**所以监听器都是基于观察者设计模式的
三个组成部分:
- 事件源:出发事件的对象
- 事件:出发的动作,封装事件源
- 监听器:当事件源触发事件后,可能完成的功能。
一、监听对象的监听器:
1、ServletContextListener:用于监听ServletContext对象的创建和销毁。
核心方法:
返回值 | 方法名 | 作用 |
---|---|---|
void | contextInitialized(ServletContextEvent sce) | 对象创建时执行的方法 |
void | contextDestroyed(ServletContextEvent sce) | 对象销毁时执行的方法 |
参数:ServletContextEvent :代表事件对象。
事件对象中封装了事件源,也就是ServletContext。
真正的事件指的是创建或销毁ServetContext对象的操作。
2、HttpSessionListener:用于监听HttpSession对象的创建和销毁。
核心方法:
返回值 | 方法名 | 作用 |
---|---|---|
void | sessionCreated(HttpSessionEvent se) | 对象创建时执行的方法 |
void | sessionDestroyed(HttpSessionEvent se) | 对象销毁时执行的方法 |
参数:HttpSessionEvent :代表事件对象。
事件对象中封装了事件源,也就是HttpSession。
真正的事件指的是创建或销毁HttpSession对象的操作。
3、ServletRequestListener:用于监听ServletRequest对象的创建和销毁。
同上
二、监听域对象属性变化的监听器
4、ServletContextAttributeListener:用于监听ServletContext应用域中属性的变化。
核心方法:
返回值 | 方法名 | 作用 |
---|---|---|
void | AttributeAdded(ServletContextAttributeEvent scae) | 域中添加属性执行的方法 |
void | AttributeRemoved(ServletContextAttributeEvent scae) | 域中移除属性执行的方法 |
void | AttributeReplaced(ServletContextAttributeEvent scae) | 域中替换属性执行的方法 |
5、HttpSessionAttributeListener:用于监听HttpSession会话域中属性的变化。
核心方法:
返回值 | 方法名 | 作用 |
---|---|---|
void | AttributeAdded(HttpSessionBindingEvent scae) | 域中添加属性执行的方法 |
void | AttributeRemoved(HttpSessionBindingEvent scae) | 域中移除属性执行的方法 |
void | AttributeReplaced(HttpSessionBindingEvent scae) | 域中替换属性执行的方法 |
6、ServletRequestAttributeListener:用于监听ServletRequest请求域中属性的变化。
核心方法:
返回值 | 方法名 | 作用 |
---|---|---|
void | AttributeAdded(ServletRequestAttributeEvent scae) | 域中添加属性执行的方法 |
void | AttributeRemoved(ServletRequestAttributeEvent scae) | 域中移除属性执行的方法 |
void | AttributeReplaced(ServletRequestAttributeEvent scae) | 域中替换属性执行的方法 |
三、监听会话相关的感知型监听器
7、HttpSessionBindingListener:用于感知对象和会话域绑定的监听器。
核心方法:
返回值 | 方法名 | 作用 |
---|---|---|
void | valueBound(HttpSessionBindingEvent scae) | 数据添加到会话域中(绑定)执行的方法 |
void | valueUnbound(ServletRequestAttributeEvent scae) | 数据从会话域中移除(解绑)执行的方法 |
8、HttpSessionActivationListener:用于感知会话域中对象钝化和活化的监听器。
核心方法:
返回值 | 方法名 | 作用 |
---|---|---|
void | sessionwillPassivate(HttpSessionEvent se) | 会话域中数据钝化时执行的方法 |
void | sessionDidActivate(ServletRequestEvent se) | 会话域中数据活化时执行的方法 |
四、监听器的使用
以ServletContextListener为例:
//该注解意思是告知服务器这是一个监听器
@WebListener
public class ServletContextListenerDemo implements ServletContextListener { //ServletContext对象是当应用一启动就被创建
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//创建ServletContext对象
ServletContext servletContext = servletContextEvent.getServletContext();
System.out.println(servletContext);
System.out.println("这是监听到ServletContext对象创建时所执行的方法");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("这是监听到ServletContext对象销毁时所执行的方法");
}
}
以ServletContextAttributeListener为例:
//该注解意思是告知服务器这是一个ServletContext属性监听器
@WebListener
public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener{ //该监听器会监听ServletContext的属性值是否有变动执行对应的方法
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("监听到了ServletContext属性被添加的方法");
ServletContext servletContext = servletContextAttributeEvent.getServletContext(); //获取ServletContext对象
Object username = servletContext.getAttribute("username"); //获取ServletContext的属性
System.out.println(username);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("监听到了ServletContext属性被移除的方法");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("监听到了ServletContext属性被替换的方法");
}
}