一.Javaweb
1.常见软件系统体系结构
1.C/S
架构
C/S
结构即客户端/服务器(Client/Server
),例如需要编写服务器端程序,以及客户端程序,例如我们安装的就是
缺点:软件更新时需要同时更新客户端和服务器端两端,比较麻烦;
优点:安全性比较好。
2.B/S
架构
B/S
结构即浏览器/服务器(Browser/Server
);优点:只需要编写服务器端程序,不需要安装专门的客户端软件,只需要浏览器就行;
缺点:安全性较差。
2.web资源
Web(World Wide Web)
称为万维网,简单理解就是网站,它用来表示Internet
主机上供外界访问的资源。
Internet
上供外界访问的资源分为:
- 静态资源
- 动态资源
1.静态资源
供人们浏览的数据始终是不变;
浏览器能直接看懂
例如:HTML
、CSS
、JavaScript
、各种图片
2.动态资源
供人们浏览的数据是由程序产生的,不同时间点访问WEB
页面看到的内容各不相同。
客户端请求的页面如果是静态网页,那么服务器会直接把静态网页的内容响应给客户端。如果客户端请求的是动态网页,服务器需要先把动态网页转换成静态网页,然后再把转换后的静态网页响应给客户端。
注:从广义上讲,用户看到的都是静态网页。
例如:Servlet
、JSP
、ASP
、PHP
,但是在Java
里面只涉及JSP/Servlet
在Java中,动态web资源开发技术统称为JavaWeb
3.web服务器
Web
服务器是运行及发布Web
应用的容器,只有将开发的Web
项目放置到该容器中,才能使网络中的所有用户通过浏览器进行访问。
1.常见web服务器
开源:
Tomcat
:主流Web
服务器之一,适合初学者Jetty
:运行效率比Tomcat
高Resin
:所有开源服务器软件中,运行效率最高的- 三者的用法从代码角度完全相同,只有在开启、关闭服务器软件时对应的命令稍有区别。掌握一个即掌握所有
收费:
WebLogic
:Oracle
WebSphere
:IBM
- 提供相应的服务与支持,软件大,耗资源
2.Tomcat
Tomcat
是Apache
软件基金会(Apache Software Foundation
)的Jakarta
项目中的一个核心项目,免费开源、并支持Servlet
和JSP
规范。目前Tomcat
最新版本为9.0
。
Tomcat
技术先进、性能稳定,深受Java
爱好者喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web
应用服务器。
二.Servlet
1.配置
1.IDEA
集成Tomcat
2.IDEA
创建Web
项目
1.新建普通Java项目
注意:Idea2020
无法直接新建JavaWeb
项目,只能通过新建普通Java
项目的方式间接新建JavaWeb
项目。
选择项目位置和普通Java
项目相同,此处略过。
2.修改普通Java
项目为JavaWeb
项目
项目根目录->右键->Add Framework Support
选择JavaEE
版本
勾选左侧的Web Application
完成之后,可以看到项目下新建了
web
目录,并包含如下内容。
添加相关依赖
File->Project Structure
执行上述操作之后,
Tomcat
相关Jar
包就添加到了项目中,不添加后续很多开发无法进行。
3.项目部署
此处指的是将
Idea
中开发的Web
项目在Tomcat
中部署。
修改
index.jsp
的代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Index</title>
</head>
<body>
<%
String name = "张三";
out.print("<p>" + name + "</p>");
%>
<p>Hello JavaWeb</p>
</body>
</html>
4.项目运行
单击运行按钮,运行项目,默认会在浏览器中打开
index.jsp
在以后的开发中,多数时候都是重复上述步骤进行JavaWeb项目的开发。
2.简介
Server Applet
(服务器小程序),是由服务器端调用和执行的、按照Servlet
自身规范编写的Java
类。
JavaWeb
的三大组件(Servlet
、Filter
、Lisener
)之一,是动态资源的一种。
作用:
- 接收请求
- 处理数据
- 完成响应
后续我们学习Servlet
也是集中在这三点。
3.实现Servlet的三种方式
Servlet
是单例的,一个类型的Servlet
只有一个实例对象,那么就有可能会出现一个Servlet
同时处理多个请求,Servlet
不是线程安全的,不应该在Servlet
中创建成员变量,因为可能会存在一个线程对这个成员变量进行写操作,另一个线程对这个成员变量进行读操作。
- 不要在
Servlet
中创建成员,创建局部变量即可; - 可以创建无状态成员;
- 可以创建有状态的成员,但状态必须为只读的。
1.实现Servlet接口
javax.servlet.Servlet
代码
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
Servlet
中的大多数方法不由我们来调用,而是由Tomcat
来调用,并且Servlet
的对象也不由我们来创建,由Tomcat
来创建!生命周期方法
init()
- 服务器会在
Servlet
第一次被访问时创建Servlet
,在Servlet
被创建后,服务器会马上调用Servlet
的void init(ServletConfig)
方法;- 在整个
Servlet
的生命周期中,该方法只被调用一次。service()
- 当服务器每次接收到请求时,都会去调用
Servlet
的service()
方法来处理请求;- 每次处理请求都会被调用
destroy()
- 在服务器被关闭时,服务器会去销毁
Servlet
,在销毁Servlet
之前服务器会先去调用Servlet
的destroy()
方法;- 在整个
Servlet
的生命周期中,该方法只被调用一次。生命周期方法方法演示
package tech.code2048.servlet;
import javax.servlet.*;
import java.io.IOException;
public class BServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init...");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service...");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("destroy...");
}
}
在
web.xml
中配置Servlet
<servlet>
<servlet-name>bServlet</servlet-name>
<servlet-class>tech.code2048.servlet.BServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>bServlet</servlet-name>
<url-pattern>/bServlet</url-pattern>
</servlet-mapping>
启动
tomcat
->访问BServlet
->关闭tomcat
观察控制台的打印。
关于
ServletConfig
- 一个
ServletConfig
对象对应一段web.xml
中的配置信息ServletConfig
是一个接口,该接口实现类的对象由Tomcat
提供- 方法
getInitParameter(name)
获取servlet
的初始化参数getInitParameterNames()
getServletContext()
getServletName()
修改
BServlet
代码
package tech.code2048.servlet;
import javax.servlet.*;
import java.io.IOException;
public class BServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init...");
System.out.println(servletConfig.getInitParameter("name"));
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service...");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("destroy...");
}
}
修改
web.xml
关于BServlet
的配置
<servlet>
<servlet-name>bServlet</servlet-name>
<servlet-class>tech.code2048.servlet.BServlet</servlet-class>
<!-- BServlet初始化参数 -->
<init-param>
<param-name>name</param-name>
<param-value>zhangsan</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>bServlet</servlet-name>
<url-pattern>/bServlet</url-pattern>
</servlet-mapping>
2.继承GenericServlet
类
GenericServlet
使编写Servlet
变得更容易。它提供生命周期方法init
和destroy
的简单实现,要编写一般的Servlet
,只需重写抽象service
方法即可。代码如下:
package tech.code2048.servlet;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class CServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("CServlet....");
}
}
web.xml`配置`CServlet
<servlet>
<servlet-name>cServlet</servlet-name>
<servlet-class>tech.code2048.servlet.CServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cServlet</servlet-name>
<url-pattern>/cServlet</url-pattern>
</servlet-mapping>
3.继承HttpServlet
类
HttpServlet
类是GenericServlet
的子类,它提供了对HTTP
请求的特殊支持,所以通常我们都会通过继承HttpServlet
来完成自定义的Servlet
。在
HttpServlet
的service(HttpServletRequest,HttpServletResponse)
方法会去判断当前请求是GET
还是POST
,如果是GET
请求,那么会去调用本类的doGet()
方法,如果是POST
请求会去调用doPost()
方法,这说明我们在子类中去覆盖doGet()
或doPost()
方法即可。
package tech.code2048.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class DServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet.......");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost........");
}
}
web.xml`配置`DServlet
<servlet>
<servlet-name>dServlet</servlet-name>
<servlet-class>tech.code2048.servlet.DServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dServlet</servlet-name>
<url-pattern>/dServlet</url-pattern>
</servlet-mapping>
4.配置Servlet
的两种方式
1.web.xml
方式
Servlet2.5
及之前使用该方式
<!-- 1、添加servlet节点 -->
<servlet>
<!-- Servlet的名字,和2中的名字必须一致 -->
<servlet-name>aServlet</servlet-name>
<!-- Servlet的全类名 -->
<servlet-class>tech.code2048.servlet.AServlet</servlet-class>
<!-- 配置启动加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 2、添加servlet-mapping节点 -->
<servlet-mapping>
<!-- Servlet的名字,和1中的名字必须一致 -->
<servlet-name>aServlet</servlet-name>
<!-- Servlet的访问路径,通过该路径可以访问doServlet的Get或doPost方法 -->
<url-pattern>/aServlet</url-pattern>
</servlet-mapping>
url-pattern
定义匹配规则,取值说明:
- 精确匹配
/具体的名称
只有url路径是具体的名称的时候才会触发Servlet
- 后缀匹配
*.xxx
只要是以xxx
结尾的就匹配触发Servlet
- 通配符匹配
/*
匹配所有请求,包含服务器的所有资源- 通配符匹配
/
匹配所有请求,包含服务器的所有资源,不包括jsp
load-on-startup
- 元素标记容器是否应该在
web
应用程序启动的时候就加载这个servlet
;- 它的值必须是一个整数,表示
Servlet
被加载的先后顺序;- 如果该元素的值为负数或者没有设置,则容器会当
Servlet
被请求时再加载;- 如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个
Servlet
,值越小,Servlet
的优先级越高,就越先被加载。值相同时,容器就会自己选择顺序来加载。
2.注解方式
Servlet3.0
新增特性,推荐使用
@WebServlet
常用属性:
name
:Servlet
名字,可选value
:配置url
路径,可以配置多个urlPatterns
:配置url
路径 ,和value
作用一样,不能同时和value
使用loadOnStartup
:配置Servlet
的创建的时机, 如果是0或者正数,启动程序时创建,如果是负数,则访问时创建。 数子越小优先级越高。
package tech.code2048.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "EServlet", value = "/eServlet", loadOnStartup = 1)
public class EServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet...");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost...");
}
}
5.常见问题
-
HTTP Status 404
资源找不到
- 第一种情况:地址书写错误;
- 第二种情况:地址没有问题,把
IDEA
项目中out
目录删除,然后重新运行。
-
Servlet
地址配置重复,多个Servlet
的url-pattern
使用相同的值 -
Servlet
地址配置错误,比如没有写/