深入理解servlet
深入理解servlet
web项目目录结构
webapp
- static:静态资源
- WEB-INF:Tomcat无法访问此目录
- classes:字节码文件(后端java代码)
- lib:项目依赖类库
- web.xml:核心web配置,后端代码的入口
静态资源和动态资源的区别
-
静态资源每次访问源代码不会发生改变
-
动态资源每次访问代码都有可能会发生改变
-
servlet其实就是动态资源开发技术(Java)
继承HttpServlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14/**
* @description 接收get请求
* @param req
* @param resp
* @return void
* @author zhuweitung
* @date 2020/9/14
*/
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello servlet, " + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
}
}web.xml中配置
1
2
3
4
5
6
7
8
9
10
11
12
13<servlet>
<!--servlet自定义名称-->
<servlet-name>HelloServlet</servlet-name>
<!--servlet对应类路径-->
<servlet-class>com.zhuweitung.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet路径映射-->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<!--对外暴露的地址-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>或使用注解
@WebServlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16@WebServlet("/hello2")
public class HelloServlet2 extends HttpServlet {
/**
* @description 接收get请求
* @param req
* @param resp
* @return void
* @author zhuweitung
* @date 2020/9/14
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello servlet, " + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
}
}
-
servlet的生命周期
- init():只会执行一次,执行初始化操作
- service():处理请求,执行doGet或doPost
- destroy():只执行一次,执行销毁操作
servlet只会初始化一次,多个请求同时访问servlet时只会实例化一次,即**servlet是单例(懒汉式)**的。
证明:由于servlet是通过xml配置文件或注解来生成的,所以是通过反射并调用servlet实现类的无参构造实例化的,只要在无参构造函数中输出即可证明
servlet自动加载
由于servlet是懒汉式单例模式的,当有请求时servlet才会被实例化,若要实现自动加载可以使用一下方法:
-
在xml中配置
load-on-startup
1
2
3
4
5
6
7
8<servlet>
<!--servlet自定义名称-->
<servlet-name>HelloServlet</servlet-name>
<!--servlet对应类路径-->
<servlet-class>com.zhuweitung.servlet.HelloServlet</servlet-class>
<!--自动加载-->
<load-on-startup>1</load-on-startup>
</servlet> -
在注解
@WebServlet
中加上loadOnStartup = 1
1
@WebServlet(value = "/hello2", loadOnStartup = 1)
servlet线程不安全
证明
1 |
|
两个浏览器进行访问,结果都显示第一次访问。
加锁解决线程安全问题。
注:使用servlet时不要使用共享全局变量。
servlet上下文
ServletContext也叫做“公共区域”,在同一个WEB应用程序中,所有的Servlet和JSP都可以共享同一个区域。
ServletContext在WEB服务器启动时创建,服务器关闭时销毁。
转发与重定向
转发
1 |
|
转发的特点:
- 地址栏不发生变化
- 只有一次请求
- 转发地址中不需要加上下文地址
- 请求域中的数据不会丢失
- 是服务端行为
- 效率高
重定向
1 |
|
重定向的特点:
- 地址栏中地址变为重定向后的地址
- 请求两次(客户端第一次请求后响应
302
状态,再请求重定向地址) - 重定向地址中需要加上下文地址以保证路径的正确
- 请求域中的数据丢失
- 是客户端行为
- 效率低
深入理解servlet
https://blog.kedr.cc/posts/3236163550/