新建
org.apache.maven.archetypes:maven-archetype-webapp
报错405的解决方法:
没有在运行地址,进行do方法的重写
一句话总结执行过程:
浏览器 Tomcat服务器 我们的应用 应用中的web.xml FirstServlet 相应浏览器
继承Httpservlet
承HttpServlet,它是jakarta.servlet.http包下的一个抽象类,是GenericServlet的子类。如果我 们选择继承HttpServlet时,只需要重写doGet和doPost方法,不要覆盖service方法。
应该还有 into delete 等几种方法
得出HttpServlet的使用结论: 我们继承了HttpServlet,需要重写里面的doGet和doPost方法来接收get方式和post方式的请求。 为了实现代码的可重用性,我们只需要在doGet或者doPost方法中一个里面提供具体功能即可,而另外 的那个方法只需要调用提供了功能的方法。
因为继承的方法里边有doget 和dopost ,在新的方法中将这两个方法重写即可
get有数据显示,一般用于查询
http的七种请求方式: do post put delete trace options head
在web.xml中配置selvet 时,selvet要写在一起,不能分开写
在Tomcat中的项目无法部署,但是可以在控制台进行结果的输出
在操做的时候,只进行了doget 和dopost方法,其余方法应该有内置操作
public class Servlet03 extends HttpServlet {
//alt+ins 进行覆盖重写
//在控制台进行输出
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("加载并初始化完成");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("正在努力运行中。。。。。");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
@Override
public void destroy() {
System.out.println("感谢干掉我");
}
}


在 Servlet 的整个生命周期中,创建 Servlet 实例、init() 方法和 destory() 方法都只执行一次。当初始 化完成后,Servlet 容器会将该实例保存在内存中,通过调用它的 service() 方法,为接收到的请求服 务。 总结: servlet对象只会创建一次,销毁一次,所以Servlet对象只有一个实例,如果一个对象实例在应用中是 唯一的存在,那么就被称为单例。
Servlet 初始化是其生命周期的第一个阶段,也是其他阶段的基础。只有完成了初始化,Servlet 才能处 理来自客户端的请求。 Servlet 初始化阶段分为 2 步: 1. 加载和实例化 Servlet; 2. 调用 init() 方法进行初始化。
Tomcat 的使用
log文件夹是日志
ServletConfig的使用 它需要使用<servlet> 标签中的<init-param> 标签来配置
<servlet>
<servlet-name>Serclet04</servlet-name>
<servlet-class>com.by.Servlet04</servlet-class>
<init-param>
<param-name>eeee</param-name>
<param-value>ffff</param-value>
</init-param>
<init-param>
<param-name>rrrr</param-name>
<param-value>ggggg</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Serclet04</servlet-name>
<url-pattern>demo04</url-pattern>
</servlet-mapping>
在进行映射的时候如果没有“/”肯定会报错
在使用注解时不需要配置xml文件
//直接注解使用
@WebServlet("/demo07")
public class Servlet07 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("注解开发");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
建好一个新的模板,检查是否少包
导入jakarta的架包
启动失败原因:
启动子级失败
注释的地方少加“/”
或者在进行编写.xml文件的时候,写url的时候没有在注解地址前加"/"
两种输出方式:getoutputstream和 printwrite
String str = "output输出字节流对象,输出到浏览器中";
ServletOutputStream outputStream = resp.getOutputStream();
outputStream.write(str.getBytes("GBK"));
System.out.println("查看控制台输出");
全局错误页面的跳转
<!--全局设置的异常错误 ,只要有错误就会跳转到error.jsp页面中 ,不管有没有设置错误跳转路径-->
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<!--应该是有404的错误信息就会跳转-->
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>
</web-app>
include
语法格式:<%@include file="" %>该指令是包含外部页面。
在a页面中含有这个语句,当使用这个语句时,可以跳转到指定的页面


jsp调用Java方法
@WebServlet("/jspdemo02")
public class JspDemo02 extends HttpServlet {
//实现jsp调用java类的方法
public static int sta(int x, int y) {
// System.out.println(a-b);
return x - y;
}
直接在jsp方法中调用Java方法
<%
sta =com.by.JspDemo02.sta(x,y);
System.out.printf("输出调用com.by包的sta的值为: ");
//这里使用sout不能输出,好像只能使用Out.print
System.out.println(sta);
out.println(sta);
%>
taglib指令
语法格式:<%taglib uri="" prefix=""%>
作用:该指令用于引入外部标签库。html标签和jsp标签不用引入。
属性:
uri:外部标签的URI地址。
prefix:使用标签时的前缀。
不能运行:
单个也不能运行

一个很有意思的问题:七个地方报错,但是可以正常运行

JSP中的九大隐式对象
什么是隐式对象呢?它指的是在jsp中,可以不声明就直接使用的对象。它只存在于jsp中,因为java类中的变量必须要先声明再使用。其实jsp中的隐式对象也并非是未声明,只是它是在翻译成.java文件时声明的。所以我们在jsp中可以直接使用
隐式对象中含有四大基本作用域
隐式对象名称 | 类型 | 备注 |
request | javax.servlet.http.HttpServletRequest | |
response | javax.servlet.http.HttpServletResponse | |
session | javax.servlet.http.HttpSession | Page指令可以控制开关 |
application | javax.servlet.ServletContext | |
page | Java.lang.Object | 当前jsp对应的servlet引用实例 |
config | javax.servlet.ServletConfig | |
exception | java.lang.Throwable | page指令有开关 |
out | javax.servlet.jsp.JspWriter | 字符输出流,相当于printwriter |
pageContext | javax.servlet.jsp.PageContext | 很重要 |
pageContext并没有将其余的属性包含,怎么搞:

RequestDispatcher.forward()方法仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址。
HttpServletResponse.sendRedirect()方法则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。
request.getRequestDispatcher()是请求转发,前后页面共享一个request ; 这个是在服务端运行的,对浏览器来说是透明的。
response.sendRedirect()是重新定向,前后页面不是一个request。而这个是在浏览器端运行的。
四大作用域
域对象名称 | 范围 | 级别 | 备注 |
PageContext | 页面范围 | 最小,只能在当前页面用 | 因范围太小,开发中用的很少 |
ServletRequest | 请求范围 | 一次请求或当期请求转发用 | 当请求转发之后,再次转发时请求域丢失 |
HttpSession | 会话范围 | 多次请求数据共享时使用 | 多次请求共享数据,但不同的客户端不能共享 |
ServletContext | 应用范围 | 最大,整个应用都可以使用 | 尽量少用,如果对数据有修改需要做同步处理 |
过滤器的使用
过滤器——Filter,它是JavaWeb三大组件之一。另外两个是Servlet和Listener 常见应用场景:URL级别的权限控制;过滤敏感词汇;中文乱码问题等等。
返回值 | 方法名 | 作用 |
void | (FilterConfig config) | 初始化方法 |
void | doFilter(resp,filterChain) | 对请求资源和响应资源过滤 |
void | destory() | 销毁方法 |
filterChain的作用
chain.doFilter将请求转发给过滤器链下一个filter , 如果没有filter那就是你请求的资源
@WebServlet("/*") 注解方式个filter方法好像是一样的,filter方法是在 .xml文件中进行编写的
//全局变量的跳转,在xml文件中设置的
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>com.by.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/filter01</url-pattern>
</filter-mapping>
HttpServletRequest接口表示浏览器请求,你可以通过这个类获取浏览器发送到服务器的任何信息
HttpServletResponse接口则用于控制服务器发送给客户端的内容
resp.getWriter().write(str)这行代的作用是在浏览器页面进行输出
过滤器的执行是全局变量
在执行jsp页面的时候,首先执行在xml中设置的过滤器,那个mapping靠前,先执行那个,在执行jsp里边的语句时,当执行完jsp的时候,在执行过滤器的结束,先执行的过滤器后结束
过滤器实质就是一个jsp页面的继承Filter方法,实现重写,先重写doFilter方法,在该方法结束的时候,使用filterChain方法进入到下一个过滤器
初始化的xml中的文件配置
<filter>
<filter-name>FilterDemo03</filter-name>
<filter-class>com.by.FilterDemo03</filter-class>
<!--相当于设置的属性类-->
<!--init-param> 初始化参数的设置-->
<init-param>
<!--param:参数-->
<param-name>filterName</param-name>
<param-value>filterValue</param-value>
</init-param>
</filter>
创建(初始化)(init)
在进行初始化服务的时候,可以进行初始化参数的设置 ,使用关键字param,也是在filter方法中设置的
提供服务(创建)(dofliter)
销毁(destory)
public class FilterDemo03 implements Filter {
@Override
/*初始化*/
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化过滤器");
/* final String filterName = filterConfig.getFilterName();
System.out.println("filterName: "+ filterName);
*//*parameter 参数*//*
*//*获取初始化的参数*//**/
/*参数的*/
/*获取参数的值*/
String filterName1 = filterConfig.getInitParameter("filterName");
System.out.println("filterName1: "+filterName1);
Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
System.out.println("initParameterNames: "+initParameterNames);
String name = filterConfig.getInitParameter("filterName");
System.out.println("name: "+name);
final String filterName = filterConfig.getFilterName();
System.out.println("filterName: "+filterName);
final String filterName2 = filterConfig.getInitParameter("filterName");
System.out.println("filterName: " + filterName2);
}
@Override
/*过滤*/
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter正在执行dofilter03方法中。。。。。。");
//执行中文乱码问题
servletResponse.setContentType("text/html;Charset=utf-8");
//过滤器进行放行,进入下一次的过滤
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("Filter还在努力执行dofilter03方法中。。。。。。, 请让我继续努力工作");
}
@Override
/*销毁*/
public void destroy() {
System.out.println("过滤器销毁");
}
}
输出的结果

当写的代码自动跳到设置的错误页面的时候,可以在每一步设置输出,在控制台查看输出的步骤,在判断哪里出现了错误
Servlet监听器-Listener操作
观察者设计模式, 所有的监听器都是观察者设计模式的体现。
什么是观察者设计模式呢? 它是事件驱动的一种体现形式。就好比在做什么事情的时候被人盯着。当对应做到某件事时, 触发事件。
观察者模式通常由以下三部分组成: 事件源:触发事件的对象。 事件:触发的动作,里面封装了事件源。 监听器:当事件源触发事件时,要做的事情。一般是一个接口,由使用者来实现。
返回值 | 方法名 | 作用 |
void | contextInitialized(ServletContextEvent sce) | 对象创建时执行此方法 |
void | contextDestroyed(ServletContextEvent sce) | 对象销毁执行此方法 |
HttpSessionListener:用于监听HttpSession对象创建和销毁的监听器
ServletRequestAttributeListener:用于监听ServletRequest域(请求域)中属性发生变化的监听器
核心方法:
返回值 | 方法名 | 作用 |
void | attributeAdded(ServletRequestAttributeEvent srae) | 域中添加了属性触发此方法 |
void | attributeRemoved(ServletRequestAttributeEvent srae) | 域中删除了属性触发此方法 |
void | attributeReplaced(ServletRequestAttributeEvent srae) | 域中属性发生改变触发此方法 |
监听器的创建以及属性的更新
public class ListenDemo01 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象的创建");
//获取对象 ger
ServletContext servletContext = sce.getServletContext();
System.out.println("servletContext ="+servletContext);
//设置属性 set
servletContext.setAttribute("username","lisi");
//替换属性 set
servletContext.setAttribute("username","zhangsan");
//移除属性 remove
servletContext.removeAttribute("username");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听器已经销毁");
}
HttpSessionAttributeListener:用于监听HttpSession域(会话域)中属性发生变化的监听器
核心方法:
返回值 | 方法名 | 作用 |
void | attributeAdded(HttpSessionBindingEvent se) | 域中添加了属性触发此方法 |
void | attributeRemoved(HttpSessionBindingEvent se) | 域中删除了属性触发此方法 |
void | attributeReplaced(HttpSessionBindingEvent se) | 域中属性发生改变触发此方法 |
@WebListener
public class ListenDemo01 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象的创建");
//获取对象
ServletContext servletContext = sce.getServletContext();
System.out.println("servletContext ="+servletContext);
//设置属性
servletContext.setAttribute("username","lisi");
//替换属性
servletContext.setAttribute("username","zhangsan");
//移除属性
servletContext.removeAttribute("username");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听器已经销毁");
}
}
@WebListener
public class SelvectContentAttributeListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
System.out.println("执行添加操作");
ServletContext servletContext = event.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println("添加的value的值是= " + username);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
System.out.println("执行删除操作");
ServletContext servletContext = event.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println("删除后的值是= " + username);
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
System.out.println("执行替换操作");
ServletContext servletContext = event.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println("替换后的值是= " + username);
}
}
