Tomcat:服务器端的Web容器。
在容器中部署项目。项目称为context root。
BS/CS:
浏览器服务器架构 与 客户端服务器架构。
BS:优点:不需要安装、维护成本低
缺点:服务器负荷较重。
CS:优点:充分利用客户端机器的资源。(安全要求不高的项目放到客户端执行。)
缺点:需要安装、升级维护。
Tomcat 目录结构说明
目录:
D:\MySQL\Tomcat\apache-tomcat-8.5.76-windows-x64
bin:可执行文件目录。
conf:配置文件。
lib:依赖的Java类。
logs:存放日志的文件夹。
temp:临时文件夹。
webapps:部署项目的空间。
work:工作目录。
注意:因为tomcat也是用Java和C来写的,所以需要配置环境变量。具体的操作可以自己搜索。
手动部署Web项目: 在配置好环境变量的前提下,双击bin目录下
startup.bat文件即可启动tomcat。在webapps下新建文件夹,在文件夹下创建文件夹名:WEB-INF和所需项目即可。然后就可以通过浏览器访问了。
JavaWeb_01项目流程为例:
创建Web项目:新建项目后,右键项目——添加框架支持——web应用程序。
部署Tomcat。
导入MySQL驱动。(记得将lib添加到工件,进行更新)。启动数据库。
导入Tomcat的jar包。
创建Servlet类(服务器端应用程序),命名为AddServlet,继承Tomcat中的HttpServlet。重写doPost方法(具体由表单的method决定),使用FruitDAO与数据库进行交互。
配置web.xml文件。使表单发起的action=add请求,对应调用AddServlet类。
- 常用名词解释:
- pojo
Plain Old Java Object。“普通Java对象”- dao
DAO(Data Access Object):数据访问层。封装对数据库的访问,不涉及业务逻辑。- impl
impl的全称为implement,表示实现的意思。
即用来存放接口的实现类。- 其他注意事项:
- 注意,IDEA比较特殊,项目部署在out目录下,而不是在webapps目录下。
- BaseDAO中要记得修改数据库的Driver等为自己的。
- add.html创建再web目录下。
- 点击调试按钮执行程序,这样可以随时debug。
- 更多详见CSDN文章。
继承关系
Servlet接口
GenericServlet抽象类
HttpServlet抽象子类相关方法 - 重点查看服务方法。
javax.servlet.Servlet接口:
void init(config) - 初始化方法
//客户端发送请求,service方法自动执行。
void service(requst,response) - 服务方法
void destory() - 销毁方法
javax.servlet.GenericServlet抽象类:
void service(requst,response) - 仍然是抽象方法
javax.servlet.http.HttpServlet抽象类:
void service(requst,response) - 不是抽象方法
service方法执行流程:
```java
if (method.equals("GET")) {
this.doGet(req, resp);
} else if (method.equals("HEAD")) {
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
}
doPost方法:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = lStrings.getString("http.method_post_not_supported");
this.sendMethodNotAllowed(req, resp, msg);
}
sendMethodNotAllowed方法:
private void sendMethodNotAllowed(HttpServletRequest req, HttpServletResponse resp, String msg) throws IOException {
String protocol = req.getProtocol();
if (protocol.length() != 0 && !protocol.endsWith("0.9") && !protocol.endsWith("1.0")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
```
小结:
1)继承关系:HttpServlet-> GenericServlet-> Servlet
2)Servlet中核心方法:init() 、service()、destory()
3)服务方法:当有请求过来时,service方法会自动响应(其实是tomcat容器调用的)
在HttpServlet中的service方法会分析发送请求的方式:到底是get、post还是…然后再决定调用哪个do方法。
在HttpServlet中这些do方法都是405的实现风格,所以要我们子类去实现对应的方法,否则默认会报405。
4)因此,在新建Servlet时,会考虑请求方法,从而决定重写哪个do方法。
JavaWeb_02——DemoServlet02
来设置servlet的启动先后顺序,数字越小,启动越靠前。HTTP称为超文本传输协议。
Http是无状态的。
Http请求响应包含两个部分:请求 request 和 响应 response。
queryString。form data。request payload。常见Http响应状态码:
404:找不到对应的资源。
405:当前请求的方法不支持。
500:没有找到数据库驱动/driver、url错误。为数据库内部错误。
200:正常访问。
302:客户端重定向
JavaWeb_02——DemoServlet03
因为Http协议是无状态的,服务器无法判断两次请求是否都由同一客户端发出。
所以通过会话跟踪技术来解决无状态问题。
会话跟踪技术
客户端第一次发请求给服务器,服务器获取session,获取不到,则创建新的sessionID。响应给客户端。下次客户端发送请求时,会把session带给服务器,那么服务器就可以判断是哪台客户端。
常用API
//获取当前会话,如果没有创建一个新的会话。
request.getSession();
request.getSession(true);
//获取当前会话,如果没有返回null。
request.getSession(false);
//获取会话ID
session.getId();
//判断当前session是否是新的
session.isNew();
//获取/设置session的最大非激活间隔时长,默认1800秒
session.getMaxInactiveInterval();
session.setMaxInactiveInterval(16000);
//强制让会话失效
session.invalidate();
//向session的保存作用域中保存数据
session.setAttribute(key,value);
//读取session保存作用域中key对应的value。
session.getAttribute(key);
session保存作用域
JavaWeb_02——DemoServlet04/05
session保存作用域是和具体的某一个sessionID对应的。
比如下图:浏览器通过demo04向服务器发送请求,获得了一个sessionID并且通过session.setAttribute(key,value);在保存作用域保存了数据。
那么只要sessionID一致,都可以通过session.getAttribute(key);直接获取保存作用域的数据。

JavaWeb_02——DemoServlet06/07
req.getRequestDispatcher("demo07").forward(req,resp);
resp.sendRedirect("demo07");
视图模板技术:可以在你的页面上加载保存作用域中的数据。以JavaWeb_03为例。

在服务器端引入Thymeleaf技术的步骤
//thymeleaf会将这个逻辑视图名称 对应到 物理视图 名称上去。
//逻辑视图名称: index
//物理视图名称: view-prefix + 逻辑视图名称 + view-suffix
//真正的视图名称: / index .html
super.processTemplate("index",req,resp);
在html页面中使用thymeleaf的标签:
th:if、th:unless、th:each、th:text,标签作用已注释在代码中。

request.getSession()方法获取session。
request.getServletContext()方法获取application。
相对路径下,使用../可以返回上一级。以下面的图片为例:红色即为相对路径。蓝色为绝对路径。
一般情况下最好写绝对路径,所以用th : ... = @{ }。

index.html(点击水果名称的超链接进行跳转,th:href=edit.do)——>EditServlet(获取要编辑的水果的fid,将该水果的信息放入保存作用域中,使用thymeleaf,执行super.processTemplate(“edit”,request,response) )——>edit.html(编辑完成后,提交表单,action=update.do)——>UpdateServlet(获取表单数据,使用FruitDAO与数据库进行交互,客户端重定向)——>index.html。index.html(点击删除图片,绑定th:οnclick=delFruit方法,在js中实现该方法,执行del.do)——>DelServlet(获取fid,使用FruitDAO与数据库进行交互,客户端重定向)——>index.html。
th:onclick="|delFruit(${fruit.fid})|"的解释:
使用th:onclick而不是简单的onclick。
因为fruit.fid要随着不同水果fid的变化而变化,所以要用th:onclick。
在thymeleaf使用方法时,添加竖线可以自动实现字符串拼接。
添加功能的实现逻辑:
index.html(点击添加按钮,绑定action=add.html,直接访问静态网页。)——>add.html(表单绑定action=add.do,直接访问AddServlet)
——>AddServlet(获取表单数据,使用FruitDAO与数据库进行交互,客户端重定向)——>index.html(最终回到index.html)

分页功能的实现逻辑:
JavaWeb_04.1
index.html(点击下一页按钮,绑定th:οnclick=pageNo方法,在js中实现该方法,执行index)——>IndexServlet(按页数显示)——>index.html
查询功能:
JavaWeb_04.2,暂时最终的IndexServlet版本。
index.html(点击查询,form表单传入index)——>IndexServlet(具体见注释)——>index.html
注意事项/技巧:
这里默认从index.html开始,其实是使用index,访问IndexServlet,使用thymeleaf将index——>index.html。
如果修改后页面没有更新,可以检查out文件夹中的文件是否都齐全。或者清除浏览器缓存。
查看div边距,可以使用border:1px solid red来实现。
使用ctrl+F5可以快捷刷新页面。