Servlet下篇
Servlet
作用:Servlet主要用于处理浏览器端发送的Http请求,并返回一个响应
一:注册Servlet
pom.xml中设置,浏览器是提供这个URL地址访问web资源的,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用元素和元素完成。
<servlet> <servlet-name>ServletName</servlet-name> 给该资源起个名 <servlet-class>com.qfedu.servlet.HelloServlet</servlet-class> 指定的该资源的路径 </servlet> <servlet-mapping> <servlet-name>ServletName</servlet-name> 和上面的名字一直 <url-pattern>/hello</url-pattern> </servlet-mapping>
元素用于注册Servlet,它包含有两个主要的子元素:
: 设置Servlet的注册名称
: 设置Servlet的完整类名,包名+类型形式
元素用于映射已注册的Servlet的对外访问路径,它包含有两个子元素:
:Servlet的注册名称,必须和配对的中的相同
:设置访问该Servlet资源的路径
例如,访问:http://localhost:8080/test/hello时,
Tomcat服务器截取到访问的资源名称/hello,
先从web.xml的中找匹配的url,找到后,再查找对应的;
然后从节点中找匹配的,找到后,根据的类名,创建Servlet对象,执行其中的方法
以上作为了解,以为后面我们直接使用注解的方式,就可以把复杂的xml文件代替了。
@WebServlet注解方式
注解中使用主要属性:
属性名 | |
---|---|
name | Servlet名字,可以自定义 |
value | 访问Servlet资源时匹配的路径,和urlPatterns互斥 |
urlPatterns | 允许当前Servlet有多个匹配方式,和value互斥 |
loadOnStartup | 标记容器是否启动时加载该Servlet |
initParams | 当前Servlet的初始化配置WebInitParam 注解类型 ,属性包括name和value |
// 注解实现的方法
@WebServlet(name = "HelloServlet", value = "/HelloServlet")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().write("get hello");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().write("post hello");}
}
后期网页的表单信息提交就可以使用直接发送到HelloServlet这个服务上,来接收前端页面的数据
Servlet 接口中的主要方法:
方法 | |
---|---|
void init(ServletConfig config) | 初始化Servlet |
void service(ServletRequet req, ServletResponse res) | 负责响应客户端请求 |
void destroy() | 销毁servlet对象,用于释放资源等 |
ServletConfng getServletConfig() | 获得Servlet 的相关配置信息,该方法会返回一个指向ServletConfig的引用 |
java.lang.Sring getServletInfo() | 获得Servlet开发者定义的信息 |
![]() |
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
request和response对象即然代表请求和响应,如果要获取客户机提交过来的数据,只需要找request对象。要向客户端输出数据,只需要找response对象。
HttpServletRequest接口
HttpServletRequest接口继承了ServletRequest接口
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象中的方法,可以获得请求相关信息。
主要学习get() 方法 post() 方法
1)get方式 了解
//读取get方式提交的数据 //获取请求参数 //如果参数中有中文,name=%E5%BC%A0%E4%B8%89&password=123 String queryString = request.getQueryString(); //中文乱码问题 queryString = URLDecoder.decode(queryString, "utf-8");System.out.println(queryString);
2)post方式 了解
//读取post方式提交的数据 ServletInputStream inputStream = request.getInputStream(); byte[] buff = new byte[1024]; int len = inputStream.read(buff);String string = new String(buff, 0, len); string = URLDecoder.decode(string, "utf-8"); System.out.println(string);
- 上面两种方法非常复杂。
//根据表单中输入控件的name属性值,获取表单参数 //get和post方式都可以用该方法获取表单参数 //tomcat8下,get方式下,使用getParameter方法,中文不会乱码String name = request.getParameter("name"); String pwd = request.getParameter("password");System.out.println(name); System.out.println(pwd);
HttpServletResponse
HttpServletResponse对象服务器的响应。该对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法
方 法 说 明 PrintWriter getWriter() 返回Servlet引擎创建的字符输出流对象 void addCookie(Cookie cookie) 将指定的Cookie加入到当前的响应中 void addHeader(String name,String value) 将指定的名字和值加入到响应的头信息中 String encodeURL(String url) 编码指定的URL void sendRedirect(String location) 重定向,发送一个临时的响应到客户端 void setHeader(String name,String value) 将给出的名字和值设置响应的头部 void setStatus(int sc) 给当前响应设置状态码 void setContentType(String ContentType) 设置响应的MIME类型
乱码处理
出现乱码的原因:不做任何处理时,返回的数据使用了iso-8859-1的编码,而该编码方式不支持中文,所以中文显示"???"。
response.setCharacterEncoding("utf-8"); response.setHeader("Content-Type", "text/html");
注意:如果仅使用response.setCharacterEncoding(“utf-8”),还是会显示乱码。这是由于虽然返回内容使用了utf8编码,但是浏览器加载的页面使用的是gbk编码,所以还需要设置content-type响应头。
response.setContentType("text/html;charset=utf-8");
转发和重定向
请求转发
请求对象HttpServletRequest
- 请求得转发(将请求转发到其他得servlet)
- 跳转页面
- 请求域(存取数据)
案例需求:发出请求/a映射AServlet 利用请求转发,将请求转发到BServlet
请求转发总结:
- 请求转发地址栏不动
- 请求转发是服务器行为,是服务器内部动作。
- 浏览器只有一次请求
/* @author 二手Java程序员* @since 2023/4/4 20:18*/
@WebServlet("/a")
public class AServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("AdoPost执行");/* 请求转发* path:就是要转发得Servlet对应得映射路径*/RequestDispatcher dispatcher = req.getRequestDispatcher("/b");// 执行转发dispatcher.forward(req,resp);}
}
/* @author 二手Java程序员* @since 2023/4/4 20:18*/
@WebServlet("/b")
public class BServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("BdoPost执行");}
}
请求域
请求域是指:HttpServleRequest对象相当于是容器,可以存取数据,可以在请求转发中其他类中共享数据。
- 存储数据:req.setAttribute(key,value)
- 取出数据:req.getAttribute(key)
@WebServlet("/a")
public class AServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("AdoPost执行");/* 请求转发* path:就是要转发得Servlet对应得映射路径*/req.setAttribute("name","法外狂徒张三");RequestDispatcher dispatcher = req.getRequestDispatcher("/b");// 执行转发dispatcher.forward(req,resp);}
}
/* @author 二手Java程序员* @since 2023/4/4 20:18*/
@WebServlet("/b")
public class BServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("BdoPost执行");String name = (String) req.getAttribute("name");System.out.println("在B端取出数据为:"+name);}
}
结果是:
AdoPost执行
BdoPost执行
在B端取出数据为:法外狂徒张三
一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发。
请求转发属于服务器行为
转发需要通过RequestDispatcher 接口的对象,调用 ServletRequest 的 getRequestDispatcher(String path) 方法可以获取该对象
方法 功能描述 void forward(ServletRequest request,ServletResponse response) 用于将请求转发给另一个 Web 资源。该方法必须在响应提交给客户端之前被调用
//request域 request.setAttribute("age", 10); //转发 request.getRequestDispatcher("/ForwardServlet2").forward(request, response);
重定向
重定向: 是HttpServletResponse对象完成一个动作
- 可以将请求重新跳转到Servlet
- 可以跳转页面
- 重定向是浏览动作
- 发起请求
需求:
发出请求/a 映射AServlet,利用重定向,将请求重新转发到BServlet
重定向是浏览器行为,发出/b请求,那就是从浏览器得根路径发出请求
需要些完整得项目名。
// 把转发中得代码改成如下代码 resp.sendRedirect(req.getConttextPath+"/b");
路径不需要写成/项目名/b,因为请求转发是服务器动作。b/即从服务器根路径开始访问,服务器得根路径自带项目名
一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源,称之为请求重定向。
重定向属于客户端行为。本质上是两次 HTTP 请求,对应两个 request 对象和两个 response 对象。
//重定向
//response.sendRedirect("/W08_2_Servlet/RedirectServlet2");
//response.sendRedirect("RedirectServlet2");//重定向时,不能共享request对象中的数据
request.setAttribute("id", 100);
//推荐如下写法
response.sendRedirect(request.getContextPath() + "/RedirectServlet2");
重定向时,多个Servlet不能共享request对象中的数据
重定向和转发区别
1)重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变;转发过程结束后,浏览器地址栏保持初始的URL地址不变。
2)重定向时,通过响应的结果告诉浏览器去重新发出请求访问另外一个资源;而转发是在服务器端内部将请求转发给另外一个资源。
3)转发时,调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而重定向时调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。
4)重定向时,重定向的URL以“/”开头,它是相对于WEB应用所在的服务器;转发时的URL以“/”开头,它是相对于当前WEB应用程序。
5)转发只能将请求转发给同一个WEB应用中的资源;而重定向还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
区别 | 转发 | 重定向 |
---|---|---|
行为 | 服务器行为 | 客户端行为 |
浏览器地址栏 URL 是否发生改变 | 否 | 是 |
是否共享 request 对象和 response 对象 | 是 | 否 |
是否能通过 request 域对象传递数据 | 是 | 否 |
是否支持跳转到其他应用的资源 | 否 | 是 |
路径中/ | 相对于当前web应用 | 相对于服务器 |
注解
注解(Annotaion)是一种注释,是给JVM中得Java代码看得
如:@Override 注解
元注解
注解的注解就是元注解
@Target
@Target目标,用来规定注解能用在什么位置
位置 | ElementType |
---|---|
包上 | PACKAGE |
类/接口/数组/枚举上 | TYPE |
成员变量/局部变量 | FIELD/LOCAL_VARIABLE |
方法/构造方法 | METHOD/CONSTRUCTOR |
@Retention
保留,指注解保留到什么时候,或者说叫保留至什么时候生效
ps:如果是自定义注解,一般为了通过反射技术读取注解,所以保留策略为RUNTIME
保留策略 | 解释 |
---|---|
SOURCE | 源码阶段 |
CLASS | 编译后class中有效 |
RUNTME | 运行时生效 |
注解的参数
数据类型,参数名()
一旦设置了参数,那么在使用注解时就必须给注解参数赋值
除非给参数设置了默认值
注解的参数都是为了通过反射技术去读取到注解参数中的值
实际应用
Servlet开发也支持使用注解代替xml文件,大大提高开发效率。
- @WebServlet 直接可以省略了xml中的八行代码。
关于路径的问题
关于跳转时路径
- 路径中加/,就是从根路径请求
- 路径中不加/ ,就是从当前路径请求
- 请求转发是服务器的动作,服务器的根路径是项目名,/b请求,其实是http://localhost:8080/项目名/b
- 重定向是浏览器动作,浏览器的根路径是端口,/b请求,其实是http://localhost:8080/b
idea的热部署
换句话说就是修改代码不重启服务器
前端的设置
后端的设置
可以自行百度安装热部署软件需要破解。