JavaWeb学习——Servlet学习(Reponse、Request)、转发和重定向的区别
1.Servlet简介
Servlet是sun公司提供的一门用于动态开发WEB资源的技术,sun(Sun Microsystems)公司创建于1982年,2009年4月20日被Oracle公司收购。
- 使用servlet技术步骤
- 1.编写好一个类,实现servlet接口
- 2.把开发好的Java类部署到WEB服务器中,通常我们把实现了servlet接口的Java程序,称为Servlet
2.Servlet运行过程
- ①Web服务器检查是否已经装在并创建了该Servlet的实例对象。如果装载了,直接执行第④步
- ②装载并创建Servlet实例对象
- ③调用Servlet实例对象的init()方法进行初始化
- ④创建一个用于封装HTTP请求消息的HttpServletResqurst对象和一个代表HTTP响应消息的HttpServletResponse对象。然后调用Servlet的service()方法向服务器发出请求,并将请求对象和响应对象作为参数传递进去
- ⑤WEB应用在程序被停止或重新启动之前,Servlet引擎卸载Servlet。并在卸载之前调用Sevlet的destroy()方法释放资源
过程图示:
Servlet调用图:
3.Servlet实现类
Servlet接口有两个默认实现类:GenericServlet和HttpServlet,我们把实现了Servlet接口的类都称之为Servlet
-
GenericServlet
-
GenericServlet是 Servlet 接口和 ServletConfig 接口的实现类. 但是一个抽象类. 其中的 service 方法为抽象方法
-
如果新建的 Servlet 程序直接继承 GenericSerlvet 会使开发更简洁
-
具体实现:
①. 在 GenericServlet 中声明了一个 SerlvetConfig 类型的成员变量, 在 init(ServletConfig) 方法中对其进行了初始化
②. 利用 servletConfig 成员变量的方法实现了 ServletConfig 接口的方法
③. 还定义了一个 init() 方法, 在 init(SerlvetConfig) 方法中对其进行调用, 子类可以直接覆盖 init() 在其中实现对 Servlet 的初始化.
④. 不建议直接覆盖 init(ServletConfig), 因为如果忘记编写 super.init(config); 而还是用了 SerlvetConfig 接口的方法,
则会出现空指针异常.
⑤. 新建的 init(){} 并非 Serlvet 的生命周期方法. 而 init(ServletConfig) 是生命周期相关的方法.
-
-
HttpServlet
-
HttpServlet是一个 Servlet, 继承自 GenericServlet. 针对于 HTTP 协议所定制.
-
在 service() 方法中直接把 ServletReuqest 和 ServletResponse 转为 HttpServletRequest 和 HttpServletResponse.
并调用了重载的 service(HttpServletRequest, HttpServletResponse)在service(HttpServletRequest, HttpServletResponse) 获取了请求方式: request.getMethod(). 根据请求方式有创建了doXxx() 方法(xxx 为具体的请求方式, 比如 doGet, doPost) -
实际开发中, 直接继承 HttpServlet, 并根据请求方式复写 doXxx() 方法即可.
-
好处: 直接由针对性的覆盖 doXxx() 方法; 直接使用 HttpServletRequest 和 HttpServletResponse, 不再需要强转.
-
4.使用IDEA开发Servlet
-
①新建WEB项目,并新建Servlet类
-
在项目目录下新建lib目录并将servlet的jar包导入
-
编写Servlet类,继承Httpservlet类,重写doGet和doPost方法
-
如果是post请求就在doPost方法里写代码,如果是get请求就在doGet方法里写代码.这里为了学习期间出错,我们在doGet请求里调用doPost方法
package com.muhan.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ServletTest01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //编写代码 } }
-
-
配置web.xml
<servlet> <!-- servlet-name:名称(任意,但必须与<servlet-mapping>中的servlet-name同名) servlet-class:servlet类的路径(包名+类名) --> <servlet-name>ServletTest01</servlet-name> <servlet-class>com.muhan.servlet.ServletTest01</servlet-class> </servlet> <!-- servlet-name:与<servlet>中的servlet-name同名即可 url-pattern:请求路径,格式为:/请求名 --> <servlet-mapping> <servlet-name>ServletTest01</servlet-name> <url-pattern>/servlet.do</url-pattern> </servlet-mapping>
- 当我们在网页上输入请求路径时是怎么知道是哪个Servlet呢:
- 从< servlet-mapping>的< url-pattern>:/servlet.do找到< servlet-mapping>的< servlet-name>:ServletTest01
- 再从< servlet-mapping>的< servlet-name>:ServletTest01找到< servlet>的< servlet-name>:ServletTest01
- 最后从< servlet>的:ServletTest01找到:com.muhan.servlet.ServletTest01
- 当我们在网页上输入请求路径时是怎么知道是哪个Servlet呢:
5.Servlet——Reponse
①重定向
重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它页面
-
新建info.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>Hello Servlet</h1> </body> </html>
-
在servlet中写入重定向代码:
resp.sendRedirect("info.jsp");
重定向的参数为页面的路径,但是默认路径是在web目录下,如果该文件在web目录下,就可以省略前面的路径,直接写问文件名
-
测试
我们输入的是http://localhost:8080/WEB01/servlet.do但是却重定向到http://localhost:8080/WEB01/info.jsp页面去了
②ServletContext
ServletContext官方叫servlet上下文。服务器会为每一个工程创建一个对象,这个对象就是ServletContext对象。这个对象全局唯一,而且工程内部的所有servlet都共享这个对象。所以叫全局应用程序共享对象。
-
1).ServletContext的目的就是为了让资源之间共享数据,因为Servlet之间是不嫩直接承诺书数据的,所以要依靠ServletContext对象
-
2).案例:通过servletContext对象读取网站配置文件
- 在src下创建resources目录,并在目录下新建一个jdbc.properties文件
driver=com.mysql.jdbc.Driver username=root password=123456 url=jdbc:mysql://localhost:3306/smbms
-
编写Servlet
package com.muhan.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; public class ServletTest02 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.获取配置文件路径 String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/resources/database.properties"); //2.新建Properties集合用来读取配置文件信息,Properties集合可以与流关联读取配置文件 Properties properties = new Properties(); properties.load(new FileInputStream(realPath));//将配置文件加载至集合 String driver = properties.getProperty("driver");//获取driver的值 String username = properties.getProperty("username");//获取username的值 String password = properties.getProperty("password");//获取password的值 String url = properties.getProperty("url");//获取url的值 //3.将获取到的值相应到网页 resp.getWriter().println(driver); resp.getWriter().println(username); resp.getWriter().println(password); resp.getWriter().println(url); } } ```
-
配置web.xml
<servlet-mapping> <servlet-name>ServletTest01</servlet-name> <url-pattern>/servlet.do</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ServletTest02</servlet-name> <url-pattern>/q1.do</url-pattern> </servlet-mapping>
-
启动tomcat访问http://localhost:8080/WEB01/q1.do
③一些其他常用方法
- response.setHeader(“Refresh”, “2;url=http://www.baidu.com”);两秒钟自动跳转到百度,可以跳到自身页面,用于刷新,可以带参数,若不写参数三则是刷新自身网页
- resp.setContentType();设置响应类型,如:"image/jpg"为图片类型
- resp.setCharacterEncoding(“utf-8”);设置响应编码格式为utf-8
6.Servlet——Request
① 一些常用方法
-
req.getContextPath(); //获得web项目路径 req.getRequestURI(); //请求的URL路径 req.getRemoteUser(); //获得远程的用户名 req.getRequestedSessionId(); //获SessionId; req.getServletPath(); //请求servlet的url req.getLocalAddr(); //获得本地地址 防火墙 req.getLocalName(); //获得本地名字 req.getLocalPort(); //获得访问的端口号
获取的结果:
/WEB01 /WEB01/q2.do null 921A65357F41059EC6156E08E0D054CD /q2.do 0:0:0:0:0:0:0:1 0:0:0:0:0:0:0:1 8080
②Request对象接收前端用户提交的参数
-
写前端注册页面
-
表单提交方式get/post
-
表单提交的位置:服务器形目路径/servlet对应的请求url
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>注册</title> </head> <body> <%-- Form表单 action:代表要提交的路径,表单要提交到哪里 ,可以提交到一个Servlet ${pageContext.request.contextPath}为项目的路径名, /q3.do是请求Servlet的url method: 提交表单的方式 --%> <h1>注册</h1> <form action="${pageContext.request.contextPath}/q3.do" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit"> <input type="reset"><br> </form> </body> </html>
-
写处理前端请求的Servlet
package com.muhan.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ServleTest04 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置请求和响应字符编码 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("utf-8"); //req.getParameter("控件的name");获取控件传来的值 String username = req.getParameter("username"); String password = req.getParameter("password"); //模拟匹配数据库 if (username.equals("张三")&&password.equals("123456")){ System.out.println("登陆成功,转到成功页面"); }else { System.out.println("登陆失败,提示用户重新注册"); } //打印一下从前端取来的数据,看是否取到 System.out.println(username); System.out.println(password); } }
-
配置web.xml
<servlet> <servletname>ServletTest04</servlet-name> <servletclass>com.muhan.servlet.ServleTest04</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletTest01</servlet-name> <url-pattern>/servlet.do</url-pattern> </servlet-mapping>
-
测试
-
看后台打印结果
登陆成功,转到成功页面 张三 123456
-
③Request实现请求转发
-
前端页面1
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>注册</title> </head> <body> <h1>注册</h1> <form action="${pageContext.request.contextPath}/q4.do" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit"> <input type="reset"><br> </form> </body> </html>
-
前端页面2
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>Success!!!</h1> </body> </html>
-
servlet代码
package com.muhan.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ServletTest05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //转发到成功页面 req.getRequestDispatcher("/success.jsp").forward(req,resp); } }
-
web.xml配置
<servlet> <servlet-name>ServletTest05</servlet-name> <servlet-class>com.muhan.servlet.ServletTest05</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletTest05</servlet-name> <url-pattern>/q4.do</url-pattern> </servlet-mapping>
-
测试
7.转发和重定向的区别
- 重定向:服务器告诉客户端,你去请求另一个地址.
- 属于客户端行为
- resp.sendRedirect();响应的方法
- 地址栏会变
- 不可以携带参数
- 转发:服务器自己转发到另一个请求
- 属于服务器行为
- req.getRequestDispatcher().forward(req,resp);请求的方法
- 地址栏不会变
- 可以携带参数