Tomcat
- Tomcat文件结构
- bin 可执行文件
- conf 配置文件
- lib Tomcat运行时依赖的库
- logs Tomcat日志
- temp 临时文件
- webapps 项目发布目录,里面的每一个文件夹代表一个Web项目
- work Tomcat工作目录
- Java项目文件结构
- src 存放源代码
- web 存放项目相关静态资源
- WEB-INF 存放相关配置
- 项目发布
- IDEA/eclipse集成Tomcat,直接发布启动执行
- 不使用IDE,手动到项目的web目录下使用命令
jar -cvf 打包后的名字.war .
- 虚拟目录 可以发布任意目录下的项目,不用放在webapps下
- 修改server.xml的host标签
<Context path="/地址栏输入的地址" docBase="项目真实存放路径" />
- 修改server.xml的host标签
- 虚拟主机 可以指定浏览器的地址去访问项目
- 修改server.xml的Engine标签
- 修改weindow下的host文件
Servlet
-
基本定义
- Servlet简单讲就是处理请求的程序类,一个jar文件
- Servlet程序是由WEB服务器调用的,需要一个Servlet容器比如Tomcat
-
基本使用
- 编写处理请求的Sevrlet类
// 程序类需要集成HttpServlet类 public class HelloServlet extends HttpServlet { // 重写父类处理请求的方法 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException { try { // 响应输出一句HTML文本 resp.getWriter().println("<h1>Hello Servlet</h1>"); } catch (IOException e) { e.printStackTrace(); } } }
- 创建WEB应用目录结构(tomcat寻找资源的时候要求使用的目录结构)
web(与src同级) -WEB-INF -classes(程序编译后的目标目录,手动设置到这里,默认是在src/bin下面) -web.xml(编写浏览器地址与Servlet类对应关系)
- 编写web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
- 部署项目到tomcat
- 修改tamca配置文件server.xml
- 添加
<Context path="/" docBase="项目路径..\\web" debug="0" reloadable="false" />
- reloadable=“true” 就表示有任何类发生的更新,web应用会自动重启
- 启动tomcat,输入地址(http://127.0.0.1:8080/项目名)查看结果
- 编写处理请求的Sevrlet类
-
Servlet运行过程
- web服务器收到客户端的Servlet请求
- 服务器首先检查是否创建了该Servlet对象(只会创建一个单例模式),是 --> 5,否 – > 3
- 装载并实例化一个Servlet对象
- 调用Servlet实例对象的init()方法
- 创建一个用于封装http请求消息和响应消息的对象,调用Servlet的service()方法,并传入请求和响应消息
- web程序在被停止或重新启动之前,Servlet引擎将卸载Servlet,并在此之前调用Servlet的destroy()方法
-
Servlet接口的实现类
- Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet
- HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比 -rvlet接口的功能更为强大。应继承这个类,避免直接去实现Servlet接口
- HttpServlet的service方法会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法。只需要 -写doGet或doPost方法,而不要去覆写service方法
- 覆写了service方法后,就不会执行判断了,也就不会自动执行doGet或doPost…方法
-
线程安全
- Servlet是线程不安全的(多个线程用一个实例)
- 解决方式
- 实现SingleThreadModel接口,如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。
- 同步对共享数据的操作,使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。
- 使用局部变量
-
接口方法
// 三个生命周期方法 public void init(ServletConfig config); public void service(ServletRequest req, ServletResponse res); public void destroy(); public ServletConfig getServletConfig(); public String getServletInfo();
-
ServletConfig
<web-app> <!-- 公共的全局初始化参数 --> <context-param> <param-name>p3</param-name> <param-value>v3</param-value> </context-param> <servlet> <servlet-name>XXX</servlet-name> <servlet-class>类路径</servlet-class> <!-- 非负整数(创建顺序),在服务器启动时创建 --> <!-- 不写或负数,在第一次访问时创建 --> <load-on-startup>0</load-on-start> </servlet> <!-- 每个Servlet独有的局部初始化参数 --> <init-param> <param-name>p1</param-name> <param-value>v1<param-value> </init-param> <init-param> <param-name>p2</param-name> <param-value>v2<param-value> </init-param> <servlet-mapping> <servlet-name>XXX</servlet-name> <url-pattern>访问路径</url-pattern> <servlet-mapping> </web-app>
// 获取Servlet的名字 public String getServletName(); // 获取Servlet上下文 public ServletContext getServletContext(); // 根据初始化参数的名称获取初始化参数的值 public String getInitParameter(String paramName); // 获取所有初始化参数的名字 public Enumeration getInitParameterNames();
-
GenericServlet
// Servlet接口 5个 + ServletConfig接口 4个 + 无参的init()方法
-
ServletContext域对象也叫application域
-
ServletContext是应用上下文对象,每一个应用中只有一个ServletContext对象
-
作用:可以配置和获得应用的全局初始化参数,可以实现Servlet之间的数据共享
-
生命周期:应用一加载就会创建,应用被停止则销毁
<web-app> <!-- 公共的全局初始化参数 --> <context-param> <param-name>p3</param-name> <param-value>v3</param-value> </context-param> </web-app>
// 获取存储到ServletContext中的参数值 public Object getAttribute(String name); // 获取全部参数的名字 public Enumeration getAttributeNames(); // 设置参数值 public void setAttribute(String name, Object value); // 删除参数值 public void removeAttribute(String name); // 获取初始化参数 public String getInitParameter(String name); // 获取资源的绝对路径(带盘符) public String getRealPath(String path); // 获取当前应用的访问虚拟路径 public String getContextPath();
-
-
重定向和转发
- 转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect()
- 转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变
- 转发是服务器行为,重定向是客户端行为
- 转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求
- 转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)
- 选择
- 重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发
- 因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了
-
注解开发 & Servlet3.0规范
- 使用tomcat9版本,JavaEE规范要求是8。对应的Servlet版本应该是4.0版本。企业开发为了稳定使用的是3.0版本。
- 之前的操作全部是基于Servlet2.5规范版本的,就是配置文件的方式。Servlet3.0规范支持注解开发,同时兼容2.5的配置文件开发。
-
中文乱码问题
- GET方式,没有乱码问题,在Tomcat8版本后已经解决
- POST方式,在获取请求参数之前,使用req.setCharacterEncoding(“参数值根据你html页面的编码确定”)
-
常见状态码
- 200 成功
- 302 重定向
- 304 请求资源未改变,使用缓存
- 400 请求错误,常见于请求参数错误
- 404 请求资源未找到
- 405 请求方式不支持
- 500 服务器错误