1、Mapping
- 一个Servlet可以指定一个映射路径
- 一个Servlet可以指定多个映射路径
- 一个Servlet可以指定通用映射路径
- 一个Servlet可以指定一些后缀或者前缀映射路径
Note:
- *为默认通配符
- *前面不能加映射路径
- 优先级问题:指定了固有的映射路径优先级最高,如果找不到就会走默认的请求处理
2、ServletContext
web容器在启动的时候,它会为每个web应用都创建一个对应的ServletContext对象,他代表了当前的web应用
共享数据
- 放置数据的类(
setAttribute()
) - 读取数据的类(
getAttribute()
) - XML
获取初始化参数(getInitParameter()
)
请求转发(getRequestDispatcher()
)(forward
)
读取资源文件(getResourceAsStream()
)
3、HttpServletResponse
简单分类
- 负责向服务器发送数据的方法
- 负责向浏览器发送响应头的方法
- 响应的状态码
常见应用
-
向浏览器输出消息
-
下载文件
- 要获取下载文件的路径
- 下载的文件名是啥
- 设置让浏览器支持下载(
Content-Disposition
)我们需要的东西(中文文件名用URLEncoder.encode()
进行编码,否则有可能会乱码)
- 设置让浏览器支持下载(
- 获取下载文件的输入流
- 创建缓冲区
-
获取OutputStream对象
- 将FileOutputStream流写入到buffer缓冲区,以及使用OutputStream将缓冲区中的数据输出到客户端
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //要获取文件的路径 String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/1.png"); System.out.println("下载文件的路径:" + realPath); //下载的文件名是啥 String filename = realPath.substring(realPath.lastIndexOf("\\") + 1); //设置让浏览器支持下载我们需要的文件 resp.setHeader("Content-Disposition", "attachment;filename=" + filename); //获取文件的下载输入流 FileInputStream fileInputStream = new FileInputStream(realPath); //创建缓冲区 int len = 0; byte[] buffer = new byte[1024]; //获取OutputStream对象 ServletOutputStream outputStream = resp.getOutputStream(); //将FileOutputStream流写入到buffer缓冲区,以及使用OutputStream将缓冲区中的数据输出到客户端 while ((len = fileInputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, len); } fileInputStream.close(); outputStream.close(); }
-
验证码
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //如何让浏览器三秒刷新一次 resp.setHeader("refresh","3"); //在内存中创建一个图片 BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB); //得到图片 Graphics2D graphics = (Graphics2D) image.getGraphics();//笔 //设置图片的背景颜色 graphics.setColor(Color.white); graphics.fillRect(0,0,80,20); //给图片写数据 graphics.setColor(Color.blue); graphics.setFont(new Font(null,Font.BOLD,20)); graphics.drawString(MakeRandomNum(),0,20); //告诉浏览器打开方式 resp.setContentType("image/jpeg"); //不让浏览器缓存 resp.setDateHeader("Expires",-1); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); //把图片写给浏览器 boolean write = ImageIO.write(image,"jpg",resp.getOutputStream()); } //生成随机数 private String MakeRandomNum(){ Random random = new Random(); String num = random.nextInt(9999999) + ""; StringBuilder stringBuffer = new StringBuilder(); for (int i = 0; i < 7-num.length(); i++) { stringBuffer.append(0); } num = stringBuffer.toString() + num; return num; }
-
实现重定向(
resp.sendRedirect()
)一个web资源收到客户端的请求之后,他会通知客户端去访问另外一个web资源,这个过程就叫做重定向
- 重定向与转发的区别:
相同点:
- 页面都会实现跳转
不同点:
-
请求转发的时候,url地址栏不会发生改变 307
-
重定向的时候,url地址栏会发生改变 302
4、HttpServletResponse
HttpServletResponse代表客户端的请求,用户通过Http访问服务器,Http请求中的所有信息会被封装到HttpServletResponse,通过这个HttpServletResponse的方法,获得客户端的所有请求;
应用场景:
-
获取前端传递的参数
-
请求转发
5、Cookie、Session
会话:用户打开一个浏览器,点击了很多超链接,访问了多个web资源,关闭浏览器,这个过程可以称之为会话
保存会话的两种技术:
Cookie
- 从请求中拿到cookie信息
-
服务器响应给客户端cookie
删除cookie:
- 不设置有效期,关闭浏览器,自动失效
- 设置有有效期时间为0
编码解码:
URLEncoder.encode();//编码
URLDecoder.decode();//解码
Sessino
什么是Session:
- 服务器会给每一个用户(浏览器)创建一个对象
- 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
- 用户登陆之后,整个网站它都可以访问
Cookie和Session的区别:
- Cookie是把用户的数据写给用户的服务器,浏览器保存(可以保存多个)
- Session是把用户的是数据写给用户独占的Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
- Session对象由服务器创建
使用场景:
- 保存一个用户的登陆信息
- 在整个网站中经常会使用的数据,我们将它保存在Session中
会话自动过去:(web.xml配置)
<!--设置Session默认的失效时间-->
<session-config>
<!--15分钟之后Session自动失效,以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
6、JSP
什么是JSP
Java Server Pages:Java服务器端界面,和Servlet一样,用于动态Web技术
最大特点::
- 写JSP就像写HTML
- 区别:
- HTML只给用户提供静态界面
- JSP页面中可以嵌入Java代码,为用户提供动态数据
- 区别:
JSP原理
思路:JSP到底是怎么执行的
-
代码层面没有任何问题
-
服务器内部工作
tomcat中有一个work目录
IDEA中使用Tomcat会在IDEA中产生一个work目录
页面会转变成java程序
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
JSP最终也会转变成一个Java类
JSP本质上就是一个Servlet
//初始化
public void jspInit() {
}
//销毁
public void _jspInit() {
}
//jspService
public abstract void _jspService(HttpServletRequest var1, HttpServletResponse var2) throws ServletException, IOException;
-
判断请求
-
内置了一些对象
final jakarta.servlet.jsp.PageContext pageContext; //页面上下文 jakarta.servlet.http.HttpSession session = null; //Session final jakarta.servlet.ServletContext application; //applicationComtext final jakarta.servlet.ServletConfig config; //config jakarta.servlet.jsp.JspWriter out = null; //out final java.lang.Object page = this; //page:当前页 HttpServletReqreuest reqreuestr; //请求 HttpServletResponse response; //响应
-
输出页面前增加的代码
try { response.setContentType("text/html;charset=UTF-8"); //设置响应的页面类型 pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out;
-
以上的这些对象我们可以直接在JSP页面中直接使用!
在JSP页面中:
只要是Java代码就会被原封不动的输出;
如果是HTML代码,就会被转化为
out,write();
这样的格式,输出到前端
JSP基础语法
JSP作为java技术的一种应用,它有一些自己的扩充语法(了解,知道)Java的所有语法都支持
JSP表达式
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
格式:<%= 变量或者表达式 %>
--%>
<%=new java.util.Date() %>
JSP脚本片段
<%--JSP脚本片段
作用:用来将程序的输出,输出到客户端
格式:
<%
脚本内容
%>
--%>
JSTL表达式
JSTL标签库的使用就是为了弥补HTML标签的不足;他自定义了许多标签,可以供我们使用。标签的功能和Java代码一样
核心标签(部分掌握)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
格式化标签
<%@ taglib prefix="fmt"
uri="http://java.sun.com/jsp/jstl/fmt" %>
SQL标签
<%@ taglib prefix="sql"
uri="http://java.sun.com/jsp/jstl/sql" %>
XML标签
<%@ taglib prefix="x"
uri="http://java.sun.com/jsp/jstl/xml" %>
JSTL标签库使用步骤
- 引入对应的taglib
- 使用其中的方法
- 在Tomcat中也需要引入JSTL的包,否则就会报错:JSTL解析错误
7、JavaBean
JavaBean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set
一般来说用来和数据库的字段做映射 ORM
ORM:对象映射关系
- 表 -----> 类
- 字段 -----> 属性
- 行记录 -----> 对象
8、MVC三层架构
什么是MVC: Model(模型) View(视图) Controller(控制器)
早些年:
用户直接访问控制层,控制层就可以直接操作数据库;
servlet-->CURD-->数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、梳理逻辑代码
架构:没有什么是加一层解决不了的
MVC三层架构
Model
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD (Dao)
View
- 展示数据
- 提供连接发起Servlet请求(a, form,img....)
Controller(Servlet)
- 接收用户的请求:(req:请求参数、Session信息......)
- 交给业务层处理对应的代码
- 控制视图的跳转
登陆--->接受用户的登陆请求--->处理用户的请求(获取用户登陆的参数)--->交给业务层处理登陆业务(判断用户名和密码是否正确:事务)--->Dao层查询用户名和密码是否正确--->数据库
9、Filter
Filter:过滤器,用来过滤网站的数据;
- 处理中文乱码
- 登陆验证
Filter开发步骤:
-
导包
-
编写过滤器
-
导
javax.servlet.Filter
-
实现Filter接口,重写对应的方法
public class CharacterEncodingFilter implements Filter { //初始化:在Web服务器启动的时候就已经进行初始化了,随时等待过滤对象出现 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("CharacterEncodingFilter初始化"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html"); System.out.println("CharacterEncodingFilter执行前。。。。。"); filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,如果不写,程序到这就会被拦截停止 System.out.println("CharacterEncodingFilter执行后。。。。。"); } //销毁:Web服务器关闭的时候过滤器销毁 @Override public void destroy() { System.out.println("CharacterEncodingFilter销毁"); } }
-
-
在web.xml中配置Filter
CharacterEncodingFilter com.Filter.CharacterEncodingFilter CharacterEncodingFilter /servlet/*
10、 监听器
实现一个监听器的接口
-
编写一个监听器的接口
//统计网站在线人数: 统计Session public class OnlineCountListener implements HttpSessionListener { //创建Session监听 @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { ServletContext context = httpSessionEvent.getSession().getServletContext(); System.out.println(httpSessionEvent.getSession().getId()); Integer onlinecount = (Integer) context.getAttribute("OnlineCount"); if (onlinecount == null) { onlinecount = 1; } else { int count = onlinecount; onlinecount = count + 1; } context.setAttribute("OnlineCount", onlinecount); } //销毁Session监听 @Override public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { ServletContext context = httpSessionEvent.getSession().getServletContext(); httpSessionEvent.getSession().invalidate(); Integer onlinecount = (Integer) context.getAttribute("OnlineCount"); if (onlinecount == null) { onlinecount = 0; } else { int count = onlinecount; onlinecount = count - 1; } context.setAttribute("OnlineCount", onlinecount); /* session销毁的两种情况: 1、 手动销毁 httpSessionEvent.getSession().invalidate(); 2、 自动销毁 */ } }
-
web.xml中注册监听器
com.listener.OnlineCountListener -
根据情况使用
11、过滤器、监听器常见应用
监听器:GUI编程中经常使用;
过滤器:用户登陆之后才能进入首页,用户注销之后就不能进入首页了!
-
用户登录之后,向Session中放入用户的数据
-
进入主页时要判断用户是否已经登陆;要求:过滤器实现
HttpServletRequest servletRequest1 = (HttpServletRequest) servletRequest; HttpServletResponse servletResponse1 = (HttpServletResponse) servletResponse; if (servletRequest1.getSession().getAttribute(Constant.USER_SESSION) == null) { servletResponse1.sendRedirect("/error.jsp"); } filterChain.doFilter(servletRequest, servletResponse);
12、junit单元测试
依赖:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
简单使用:
@Test注解只是在方法上有效只要加了这个注解的方法就可以直接运行
@Test
public void test() {
System.out.println("Hello");
}
成功的时候是绿色的;
失败的时候是红色的;
13、 设置首页
在web.xml文件中设置
<welcome-file-list>
<welcome-file>/Login.jsp</welcome-file>
</welcome-file-list>