servlet入门
Servlet入门
1.servlet概念:
2.Servlet初体验
通过web.xml配置,访问我创建的ServletDemo类,tomcat自带解析web.xml功能
整个项目:
package com.xurong.servlet;
import javax.servlet.*;
import java.io.IOException;
/**
* @auther xu
* @date 2022/4/2 - 13:44
*/
public class ServletDemo2 implements Servlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// servletResponse.getWriter().write("hello servlet2");
System.out.println("helloTest");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
}
xml文件代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--创建一个Servlet实例-->
<servlet>
<servlet-name>servletDemo1</servlet-name>
<servlet-class>com.xurong.servlet.ServletDemo2</servlet-class>
</servlet>
<!--给Servlet提供(映射)一个可供客户端访问的URL-->
<servlet-mapping>
<servlet-name>servletDemo1</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>
结果:没有向客户端响应响应代码,客户端并没有输出什么,不过服务器端输出了服务端运算的代码:
3.Servlet执行过程
补充:ServletDemo1没有main方法,ServletDemo类是Tomcat实例化的,其中的service()方法也是服务器调用的。
4.Servlet生命周期
1--实例化---》初始化----》服务(多个服务)----》销毁
2--理解--应用卸载了,secondServlet删除:(这个还是欧典有点懵)
注意在服务器运行时,该文件正在使用,无法卸载。
注意:设置了该管理模式需要重启服务器再来探究destroy()方法目的,服务器在运行时,将webapp卸载,也就是destroy()方法实际执行的动作,我们不能通过文件直接删除,但是可以通过管理模式,将正在运行的应用程序卸载,从而达到执行destroy目的
以上模拟了web应用程序的全过程。
特别注意:服务器停了与应用程序卸载(我理解是从内存中删除了,一个应用进程的结束,垃圾回收,并非是静态代码删除)之间的区别(服务器停了,应用程序肯定关闭卸载了,但是应用程序卸载了服务器并不一定停了,因为应用要部署到服务器上才能运行。)
3.创建一个实例,该实例中的service方法可以多次调用,体现多线程。
package com.xurong.servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.ServletException;
import javax.servlet.Servlet;
import java.io.IOException;
/**
* @auther xu
* @date 2022/3/31 - 21:43
*/
public class ServletDemo2 implements Servlet {
//Servlet生命周期的方法
//实例化方法
//在servlet第一次访问时被调用
public ServletDemo2() {
super();
System.out.println("************ServletDemo实例化了*********");
}
//Servlet生命周期的方法
//初始化
//在servlet第一次访问时被调用
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("--------init()初始化了-----------");
}
//Servlet生命周期的方法
//服务
//每一次访问时都会被调用
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// servletResponse.getWriter().write("hello helloservletDemo1");
System.out.println("---------service()方法执行了----------");
}
//Servlet生命周期的方法
//销毁
//应用卸载的时候销毁
@Override
public void destroy() {
System.out.println("------------destroy()方法执行了-----------");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--创建一个Servlet实例-->
<servlet>
<servlet-name>servletDemo1</servlet-name>
<servlet-class>com.xurong.servlet.ServletDemo2</servlet-class>
</servlet>
<!--给Servlet提供(映射)一个可供客户端访问的URL-->
<servlet-mapping>
<servlet-name>servletDemo1</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>
4.服务器已启动就实例化化与初始化设置,关于<load-on-startup>2</load-on-startup>数字问题
运行结果:
对比:
5.真正的执行过程
5.适配器模式--继承javax.servlet.GenericServlet类
作用:实现了Servlet,ServletConfig俩个接口,想调用这两个接口中的方法直接继承GernicServlet类即可
所遇到的问题:
1.报505错误:
解决:(我觉的是Tomcat中类(不同包中的非子类)实例化时,需要权限为public,default不行)
6.javax.servlet.HttpServlet
1.从一个客户端访问报错405研究doPost()与doGet()方法
1.继承的HttpServlet类的方法显示
2.HttpServlet继承的方法(对父类的方法进行重写)-----service(ServletRequest req, ServletResponse res)
3.HttpServlet自己定义的----protected void service(HttpServletRequest req, HttpServletResponse resp)方法
1.this.doGet(req,resp);
"http.method_get_not_supported"字符串内容:
2.this.doPost()方法
http.method_post_not_supported
4.通过对HttpServlet中doPost()与doGet()方法的探索总结一下
通过继承HttpServlet类,重写其方法,达到从服务器端反馈给客户端数据的目的
其原理过程:客户端发送请求----》Tomcat服务器实例化应用程序(多态:Servlet s = new ServletDemo4();)ServletDemo4类,并执行初始化init()方法----》实例化对象调用HttpServlet类对GenericServlet类重写的service()方法----》servlet()方法调用HttpServlet本类的service()方法-----》HttpServlet本类的service()方法调用ServletDemo4类中重写的doGet()与doPost()方法(采用实例化子类对象时,相同的方法在子类中重写了,会优先调用子类的方法,this句柄指向的是ServletDemo4对象,this.doGet()与this.doPost()自然指向ServletDemo4类中的方法),而非HttpServlet本类中的方法。
结果:(可以通过调试看到访问的是重写的doPost()与doGet()方法)
7.doGet()与doPost()方法设计技巧,多个映射路径可以指向一个Servlet
1.设计技巧:
注意:一般客户端访问默认是get方式
2.多个映射路径可以指向一个Servlet
使用通配符方式改进:
*.action:
/*:
/action/*:
匹配规则:
补充:
tomcat服务器自带默认的DefaultServlet(), 其中包含一个web.xml
总结:/映射也是一个DefaultSevlet,所以说所有资源都是servlet.
8.Servlet线程安全:
1.全局变量导致的线程安全问题
package com.xurong.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @auther xu
* @date 2022/4/3 - 14:48
*/
public class ServletThread extends HttpServlet {
//全局变量会导致线程安全
int i = 1;
public ServletThread() {
super();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("一个实例多个线程,当前值为:"+i);//不出意外,线程安全会出现i值不一定都是累加的
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
输出结果:
2.解决线程安全:不要定义全局变量
9.获取Servlet配置信息
方式1:
演示:
package com.xurong.servletOther;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @auther xu
* @date 2022/4/3 - 15:31
*/
public class ServletConfigureDemo extends HttpServlet {
private ServletConfig config;
public ServletConfigureDemo() {
super();
}
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取配置文件方式1:
String encodingValue = config.getInitParameter("encoding");
System.out.println(encodingValue);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
方式2:
报500错误:
错误原因:
方式3:
11.ServletContext(重要)
1.作用1:
域对象补充一下:
java代码实现:
package com.xurong.servletContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @auther xu
* @date 2022/4/4 - 9:01
*/
public class ServletContextDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取应用对象方法1:
// ServletContext application = super.getServletConfig().getServletContext();
//获取应用对象方法2:
ServletContext application = this.getServletContext();
application.setAttribute("name","Tom");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
配置路径web.xml:
结果:
小技巧:查看类名
ServletContext的超类不是Object,而是有Apach服务器提供
2.作用2:获取全局配置信息
3.作用3:获取当前应用任何位置的任何资源(只要深处该应用中)
1.WEB-INF/b.properties访问
2.src/b.properties访问
所遇问题:
3.src\com\xurong\servletContext\c.properties文件内容
12.实现servlet请求转发
13.总结:
所遇到的问题:
1.IDEA 使用Tomcat Server output输出中文乱码问题
补充Tomcat:
1.Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。
2.Tomcat包含servlet-api.jar
3.Tomcat不需要配置环境变量,很少在本地访问,一般直接部署到
其实,一般很少在本地启动Tomcat,大多数都是在开发工具(eclipse或者Idea)中集成外部本地Tomcat,无须配置环境变量,因为eclipse内部已经直接找到了Tomcat的根目录中。下面完整演示一下,Tomcat在本地的启动过程。
注意:无论何时,最后关闭IDE前一定要先关闭Tomcat服务器,有的IDE会提示你Tomcat服务器没关,有的不会提示,那么你下次启动IDE后,启动Tomcat,很大概率上会失败。电脑死机,eclipse自动闪退也会发生这种问题。如果你真的发生这种问题,可以参考我之前写的解决方案:
参考: