servlet 实现董涛页面机制
写Servlet就需要使用maven创建出一个java web的项目也需要通过maven帮我们下载到Servlet依赖的jar包.还需要借助maven 把代码打成包~~
1.先创建maven项目 补充目录结构
<?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">
</web-app>
2.引入Servlet依赖 在中央仓库下载
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>testMaven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- maven默认编译时1.5 这里设置1.8-->
<properties>
<encoding>UTF-8</encoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- 加入 servlet 依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<!-- servlet 版本和 tomcat 版本有对应关系,切记 -->
<version>3.1.0</version>
<!-- 这个意思是我们只在开发阶段需要这个依赖,部署到 tomcat 上时就不需要了不参与部署打包 -->
<scope>provided</scope>
</dependency>
</dependencies>
<packaging>war</packaging>
<build>
<finalName>helloservlet</finalName>
</build>
</project>
3.写代码 创建HelloServlet 不用main方法 继承父类HTTPServlet 重写doget/doPost方法 执行需要的代码
要用@webServlet(“/hello”)加上注解
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.text.AbstractDocument;
import java.io.IOException;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("hello world!");
//返回html内容的话 就要构造响应
//Content-Type 表示body的格式
resp.setContentType("text/html");
//获取流对象 输入输出的一类对象
resp.getWriter().write("<h3>hello world</h3>");
}
}
4.打包 使用Maven打包
要达成war包 并且指定名称
</dependencies>
<packaging>war</packaging>
<build>
<finalName>helloservlet</finalName>
</build>
5.部署 考到tomcat的webapps下面
6.访问 127.0.0.1:8080/helloservlet/hello
写一个java 代码不一定非得有main方法.
也可以是别的软件/框架提供好一个main方法(Tomcat)直接按照人家软件/框架的要求来写代码,代码就可以被自动调用起来了~~
在Servlet,是如何调用到具体代码的呢?Tomcat收到HTTP请求.
Tomcat 会分析HTTP请求的一些关键信息:
1.URL中的path, path第一级是否是webapps 下的某个目录名字(也把这一级目录名字叫做context path),确定了一个Tomcat 上的 webapp
2.URL 中的第二级path是否是该webapp下的某个类里面的注解所对应的路径.确定了该webapp下的某个Servlet类3.再根据当前是GET请求还是POST请求,确定调用
Servlet类里面的doGet还是doPost
在工作中很少会使用Servlet .这个东西写起来确实比较麻烦一点~~工作中主要是使用Spring这样的一些封装程度更高的框架.
Spring 底层其实还是Servlet.后面要想学好Spring,还是需要先对Servlet有基本的理解~
常见错误
404 检查url 注解是否正确 web.xml 路径内容是否正确
空白页面 检查resp设置的对象是否正确
500 可能会空指针
addservlet
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/add")
public class AddServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 希望 HTTP 请求中, query string 里面带有两个参数, a, b
// a 和 b 对应两个整数
// doGet 方法能够获取到 a 和 b , 并且进行相加
// 把相加的结果返回给浏览器页面.
// 如果完成了这个功能, 意味着只要请求中的参数不同, 返回的页面内容也就不同
// 也就达到了 "动态页面" 效果.
// 使用 req 里面的 getParameter 方法就能拿到 a 和 b 的值
String a = req.getParameter("a");
String b = req.getParameter("b");
int result = Integer.parseInt(a) + Integer.parseInt(b);
// 把结果返回给页面
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("<h3> 结果 = " + result + "</h3>");
}
}
访问的时候路径一定要加上query string
h ttp://127.0.0.1:8080/Addsrvlet/add?a=10&b=20
Tomcat和Servlet之间的关系.
基本概念:
容器(Container):认为Tomcat是一个webapp 的容器
上下文(Context):每个webapp就有一个独立的上下文对象.
可以借助这个上下文对象来去共享同一个webapp 中不同的Servlet类之间的数据
HttpServlet 是 Servlet 接口的一个实现类,但它本身是个抽象类,所以我们的 HelloServlet 继承 了 HttpServlet,主要负责的是 HTTP 请求的处理,根据我们要支持的方法,选择覆写 doGet 或者 doPost 或者其他合适的方法即可
Tomcat 实现的主要是 HTTP 协议,也就是应用层,同时在操作系统的视角里,是属于用户态程序。 我们自己的实现是在 Tomcat 基础上运行的。
Tomcat是一个应用程序.核心工作就是处理HTTP请求和响应.
Tomcat能够处理HTTP请求,全靠操作系统内核中的网络协议栈来支撑的.
Tomcat自身作为一个平台(webapp的容器),又对上层进行了一些支撑.给用户写的代码提供了一些服务器.
Tomcat具体提供的服务器:
1.收到HTTP请求的时候(字符串),按照HTTP协议的格式,把这个请求解析成一个HttpServletRequest 对象~
2.Tomcat根据请求的信息,(URL的路径,方法)定位到某个具体的Servlet类,以及调用其中的某个方法~
3.用户自己写的代码,就会根据HttpServletRequest的内容,动态的计算,构造生成一个HttpServletResponse 对象
4.Tomcat拿到HttpServletRepsonse对象之后又会把这个对象按照HTTP协议的格式构造成一个字符串,通过内核中的下层协议栈,发送会给浏览器.
tomcat流程
class Tomcat {
// 用来存储所有的 Servlet 对象
private List<Servlet> instanceList = new ArrayList<>();
public void start() {
// 根据约定,读取 WEB-INF/web.xml 配置文件;
// 假定是我们从配置文件中解析出的所有的 Servlet 子类(也就是我们的业务类)
Class<Servlet>[] allServletClasses = ...;
// 这里要做的的是实例化出所有的 Servlet 对象出来;