JavaWeb的技术体系
一.Tomcat服务器
Web服务器:
- Web服务器主要用来接收客户端发送的请求和响应客户端请求。
1)Tomcat服务的目录结构
2) 配置环境变量,方便Tomcat的启动关闭(可选)
- 新建环境变量CATALINA_HOME=解压目录
- 在Path环境变量中加入Tomcat解压目录\bin目录
- 在命令行中运行catalina run或者 startup启动Tomcat服务器,在浏览器地址栏访问如下地址进行测试:http://localhost:8080
- 开始页面对应的是webapps\ROOT\index.html文件
3)Tomcat端口号的修改
- 修改conf文件夹下,server.xml文件的conector标签,
- 修改8080、8005、8009端口号
4)在eclipse中配置tomcat
注意:
1.解压的Tomcat与eclipse中配置的Tomcat不是同一个,两者目录在不同的文件目录中
- ①eclipse中配置的Tomcat所在目录:
- worksapce目录.metadata.plugins\org.eclipse.wst.server.core\tmp0
- Tmp0:代表第一个servers服务器
- ②也可以在eclipse中的运行服务器上右键,打开文件所在位置
- ③Tomcat目录:tomcat安装目录\webapps\ROOT
2.eclipse中打开的的服务器,对应起始页(http://localhost:8080)在
- \tmp0\wtpwebapps\ROOT文件夹下的index.html
二.Servlet
为什么会有Servlet?
- Html是静态页面,用于显示静态资源,其缺点是不会处理请求;
- 而Servlet是服务器端用于处理请求,其作用是为了展示动态的WEB资源
1.什么是Servlet?
Servlet 运行在服务端的Java小程序,用来处理客户端请求、响应给浏览器的动态资源;
- 作用是:展示动态的WEB资源。
1)Servlet是Sun公司制定的一套技术标准:包含与Web应用相关的一系列接口,是Web应用实现方式的宏观解决方案。而具体的[Servlet容器]负责提供标准的实现。
2)Servlet作为服务器端的一个组件,它的本意是“服务器端的小程序”。
- a) Servlet的实例对象由Servlet容器负责创建;
- b) Servlet的方法由容器在特定情况下调用;
- c) Servlet容器会在Web应用卸载时销毁Servlet对象的实例。
3)简单可以理解为 Servlet就是用来处理客户端的请求的.
2.Servlet的创建
1.通过实现Servlet接口创建对应的类
public class LoginServlet implements Servlet{
…
//用来处理用户请求的方法
@Override
public void service(ServletRequest req, ServletResponse res)
…
}
2.通过继承抽象类HttpServlet来完成Servlet的创建
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
//处理get请求
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
//处理post请求
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
HttpServlet中会调用对应的service(ServletRequest req, ServletResponse res)的实现:
public abstract class HttpServlet extends GenericServlet {
…
@Override
public void service(ServletRequest req, ServletResponse res)……
}
在抽象HttpServlet中:
- 1)service()会将ServletRequest req, ServletResponse res转为
- HttpServletRequest request;
- HttpServletResponse response;
- 2)接着调用自己重载的service方法:
- protected void service(HttpServletRequest req, HttpServletResponse resp)
- 3)然后根据request的请求方式,调用对应的方法:
- GET请求:调用doGet()方法
- POST请求:调用doPost()方法
而继承自抽象类HttpServlet的具体的Servlet实现类,则重写类doGet()与doPost()方法,所以最终的方法调用的是:被实现类重写的方法。
3.Servlet处理请求的简单流程
- 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
- 查找web.xml文件,是否有对应的标签体内容。
- 如果有,则在找到对应的全类名
- tomcat会将字节码文件加载进内存,并且创建其对象
- 调用其方法
1.第一次请求Servlet:
当Browser第一次请求Sevlet时:
- 服务器会根据web.xml中的Sevlet映射,找到对应Sevlet注册信息中的Sevlet全类名;
- 然后通过反射,通过无参构造器,初始化创建对应的Servlet对象;
- 然后通过对象的service( )方法处理request与response
2.之后的Servlet请求
- 服务器只会创建一个对应的Servlet对象,此后始终使用的是这个对象的service( )方法处理request与response操作。
3.Servlet容器会在Web应用卸载时销毁Servlet对象的实例
其他注意事项:
-
1)当映射地址不存在时:浏览器会显示404——对应页面不存在的错误
-
2)当映射地址与页面地址重复时
案例:
<--! web.xml配置文件 -->
<servlet-mapping>
<servlet-name>AutoServlet</servlet-name>
<url-pattern>/index.html</url-pattern>
</servlet-mapping>
- a) 优先根据映射,调用对应的Servlet对象的处理逻辑;
- b) 如果没有该映射,则根据页面地址寻找对应页面;
- c) 如果没有对应页面,则给出404错误——没有找到对应内容
4.Servlet中的生命周期方法
5.Servlet类的相关方法:
1.doGet ( )
- Servlet中用于处理get请求的方法
2.doPost( )
- Servlet中用于处理post请求的方法
3.service ( )
- 在Servlet的顶层实现中,在service方法中具体掉用的是doGet或者是doPost
- 在实际开发Servlet的过程中,可以选择重写doGet以及doPost 或者 直接重写service方法来处理请求。
4.Servlet 3.0类
- a) 不需要web.xml文件
- b) 基于注解的方式实现
@WebServlet("/AutoServlet")
public class AutoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
6.Servlet在web.xml中的配置
1.注册servlet:<servlet>标签
用于标注Servlet实例对象的名称,以及对应的类(即全类名)
- <servlet-name>:给Servlet起一个名称,可以任意指定,通常我们以类名作为Servlet的名称
- <servlet-class>:配置Servlet接口的实现类的全类名,Servlet容器会根据全类名利用反射创建对象
2.映射Servlet:标签
用于标注Servlet实例对象名称对应的URL模式
- <servlet-name>
- <url-pattern>:映射请求地址,地址可以任意指定,在这儿指定的是什么,将来在浏览器地址栏输入的就是什么
7.获取请求参数值:HttpServletRequest
1.HttpServletRequest
- 该接口是ServletRequest接口的子接口,封装了HTTP请求的相关信息:
- 由Servlet容器创建其实现类对象并传入service(ServletRequest request, ServletResponse response)方法中。
2.HttpServletRequest对象的主要功能
-
1)获取请求参数
request.getParameter(“username”); -
2)获取项目虚拟路径:/项目名 ——绝对路径
request.getContextPath() //结果为WebContent对应的服务器路径,即/项目名 -
3)转发:将请求转发给另外一个URL地址
3.转发请求:
- 1)获取转发器request.getRequestDispatcher()
//绝对路径,等价于:http://localhost:8080/WebTest/ + pages/success.html
RequestDispatcher rd= request.getRequestDispatcher("/pages/login.html");
- 2)进行请求的转发.forward()
rd.forward(request, response);
8.响应结果:HttpServletResponse
1.HttpServletResponse
- 该接口是ServletResponse接口的子接口,封装了HTTP响应的相关信息,
- 由Servlet容器创建其实现类对象并传入service(ServletRequest req, ServletResponse res)方法中。
2.HttpServletResponse主要功能
- a) 使用PrintWriter对象向浏览器输出数据
例如:给浏览器响应一个字符串、一个对象object ,或一个页面
PrintWriter writer = response.getWriter();
Date date = new Date();
writer.write("响应成功!");
writer.print(date);
writer.write("<!DOCTYPE html>\r\n" +
"<html>\r\n" +
"<head>\r\n" +
"<meta charset=\"UTF-8\">\r\n" +
"<title>Insert title here</title>\r\n" +
"</head>\r\n" +
"<body>\r\n" +
" <h1>我是一个非常漂亮的页面!</h1>\r\n" +
"</body>\r\n" +
"</html>");
- b) 响应的重定向:response.sendRedirect()
//重定向到登录成功页面:url解析由浏览器进行,根目录到项目文件夹的父文件夹
//绝对路径,等价于:http://localhost:8080/ + WebTest/pages/success.html
response.sendRedirect(request.getContextPath()+ "/pages/success.html");
三.其他
1.请求转发
- Servlet接收到浏览器端请求后,进行一定的处理,先不进行响应,而是在服务器端内部“转发”给其他Servlet程序继续处理。在这种情况下浏览器端只发出了一次请求,浏览器地址栏不会发生变化,用户也感知不到请求被转发了。
- 转发请求的Servlet和目标Servlet共享同一个request对象。
- 实现转发的API
步骤:
- 1)获取转发器
- 2)进行请求的转发
//1)获取转发器
//绝对路径,等价于:http://localhost:8080/项目文件夹/ + pages/success.html
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/pages/login.html");
//2)进行请求的转发
requestDispatcher.forward(request, response);
2.响应重定向 sendRedirect
1)Servlet接收到浏览器端请求并处理完成后,给浏览器端一个特殊的响应(服务器response:Statu Code 302 以及 location地址),这个特殊的响应要求浏览器去请求一个新的资源;第二次请求:按照新地址,重新请求服务器,服务器返回对应结果。
- 整个过程中浏览器端会发出两次请求,且浏览器地址栏会改变为新资源的地址。
2)重定向的情况下,原Servlet和目标资源之间就不能共享请求域数据了
3)实现重定向的API
response.sendRedirect("重定向的地址");
3.重定向与转发的区别
区别 | 转发 | 重定向 |
---|---|---|
原理 | 服务器端处理 | 浏览器与服务器共同处理 |
浏览器地址栏 | 不改变 | 改变 |
发送请求次数 | 1 | 2 |
能否共享request对象数据 | 能 | 否 |
目标资源:WEB-INF下的资源 | 能访问(属于服务器端操作) | 不能访问 |
转发与重定向的区别:
- 1.转发发送一次请求;重定向发送两次请求
- 2.转发浏览器地址栏地址无变化;重定向浏览器地址栏地址有变化
- 3.转发可以访问WEB-INF目录下的资源;重定向不可以访问WEB-INF目录下的资源
- 4.转发可以共享request域中的数据;重定向不可以共享request域中的数据
4.绝对路径与相对路径
1.什么是绝对路径?
- 以 / 开头的路径即为绝对路径
- 相反,不以/ 开头的路径即为相对路径
2./ 代表的意义:
- 1)如果地址由浏览器解析,那么 / 代表http://localhost:8080/
- 2)如果地址由服务器解析,那么 / 代表http://localhost:8080/WebProject/
3.由浏览器解析的路径:
- 1)HTML标签中的路径,如a标签中href属性中的路径、form标签中action属性中的路径等。如以下路径的错误:
<!—http://localhost:8080/ + pages/login.html -->
<a href="/pages/login.html">我要登录</a>
- 2)重定向中的路径
//重定向到登录成功页面:url解析由浏览器进行,根目录到项目文件夹的父文件夹
//绝对路径,等价于:http://localhost:8080/ + WebTest/pages/success.html
response.sendRedirect(request.getContextPath()+ "/pages/success.html");
request.getContextPath():/WebTest 项目目录的绝对路径
- 即/WebTest/pages/success.html
4.由服务器解析的路径:
- 如果地址由服务器解析,那么 / 代表http://localhost:8080/WebProject/
以下路径由服务器解析:
- 1)web.xml配置文件中url-pattern标签中的路径
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<!-- http://localhost:8080/ WebTest / + LoginServlet -->
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
- 2)转发中的路径
//转发到登录页面:url解析由服务器进行,根目录到项目文件夹
//1)获取转发器
//绝对路径,等价于:http://localhost:8080/WebTest/ + pages/success.html
RequestDispatcher rd = request.getRequestDispatcher("/pages/login.html");
//2)进行请求的转发
rd.forward(request, response);
5.<base>标签设置页面相对路径为绝对路径
base标签的href属性可以让当前页面中所有的相对路径都变为绝对路径:
- 使用上下拼接的方式
注意:相对路径开头绝对不要有 /
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- base标签的href属性可以让当前页面中所有的相对路径都变为绝对路径 -->
<base href="http://localhost:8080/Web_Ex/">
</head>
……
<!—相对路径转为绝对路径:http://localhost:8080/Web_Ex/ + pages/login.html -->
<a href="pages/login.html">我要登录</a>
……
5.request与response乱码问题的解决
1.Get request 中的乱码问题
url请求中文乱码问题的解决方案:
- 在Tomcat的配置文件server.xml中的第一个Connector标签中添加属性:
- URIEncoding=“UTF-8”
2.Post request 中的乱码问题
Post请求请求中文乱码问题的解决方案:在第一次获取请求参数之前设置字符集为UTF-8
//为拿到的request设置编码格式。
request.setCharacterEncoding("UTF-8");
3.response中的乱码问题
- 响应中文乱码问题的解决方案:
//设置response的一些属性。
response.setContentType("text/html;charset=UTF-8");