Servlet简介
- 狭义上的概念:Servlet接口及其子接口
- 广义上的概念:实现了Servlet接口的实现类我们都称为Servlet
- Servlet对象由Servlet容器(如Tomcat)帮我们创建,不需要我们new
-
创建Servlet的HelloWorld的步骤
1)创建一个动态的Web工程,并创建一个类实现Servlet接口
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
//处理用户请求的方法
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("您的请求我已经收到!");
//获取一个打印流
PrintWriter writer = servletResponse.getWriter();
//给浏览器响应一个字符串
// writer.write("Response Success!");
writer.print("Response Success!");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
2)在web.xml配置文件中注册实现类
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--注册Servlet-->
<servlet>
<!--给当前的Servlet起一个名字,可以任意指定,通常我们以类名作为它的名字-->
<servlet-name>HelloServlet</servlet-name>
<!--设置Servlet接口实现类的全类名,Tomcat(Servlet容器)会通过反射技术创建实现类对象-->
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
</servlet>
<!--映射Servlet-->
<servlet-mapping>
<!--指定要引用的Servlet-->
<servlet-name>HelloServlet</servlet-name>
<!--指定要处理的请求的请求地址-->
<!--http://localhost:8080/Web_Servlet/HelloServlet-->
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
</web-app>
3)当发送HelloServlet这个请求之后,服务器会去web.xml中寻找对应的请求地址的映射,然后创建引用的Servlet实现类的实例并调用service()方法处理用户的请求
Servlet的生命周期
Servlet的生命周期即Servlet对象从被创建到被销毁的一个过程
体现Servlet生命周期的有以下方法:
ServletConfig
```java / ServletConfig:代表了Servlet的配置,该对象由Tomcat创建 该对象有以下三个作用: /
//1.获取Servlet的名称 String servletName = servletConfig.getServletName(); System.out.println(“当前Servlet的名称是:”+servletName);
//2.获取Servlet的初始化参数(只有当前Servlet才能获取,其他的Servlet无法获取) String username = servletConfig.getInitParameter(“username”); System.out.println(“当前Servlet的初始化参数username的值是:”+username);
//3.获取ServletContext对象 ServletContext servletContext = servletConfig.getServletContext();
- `ServletContext`<br />
```java
//ServletContext对象代表了当前Web应用,它也有以下三个作用:
//1.获取当前Web应用的初始化参数(所有的Servlet都可以获取)
String encoding = servletContext.getInitParameter("encoding");
System.out.println("当前Web应用的初始化参数encoding的值是:"+encoding);
//2.获取服务器中资源的真实路径(文件的上传下载时使用)
String realPath = servletContext.getRealPath("/index.html");
System.out.println("项目中的index.html的真实路径是:"+realPath);
//3.ServletContext是一个域对象(下回分解)
请求和响应
HttpServletRequest request
- request代表了浏览器发送给服务器的请求报文,该对象由服务器创建并以参数的形式传入到doGet和doPost方法中,在这两个方法中可以直接使用
- request的作用
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost方法被调用");
//request的作用:
//1.获取请求参数
/*
请求中文乱码问题的解决方案:
对于POST请求:
在第一个获取请求参数之间通过request设置字符集为UTF-8
对于GET请求
在Tomcat的配置文件server.xml的第一个Connector标签中添加属性URIEncoding="UTF-8"
*/
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username);
System.out.println(password);
//2.获取项目的虚拟路径
String contextPath = request.getContextPath();
System.out.println("项目的虚拟路径是:"+contextPath);
//3.转发
//获取转发器
RequestDispatcher requestDispatcher = request.getRequestDispatcher("WEB-INF/success.html");
//进行请求的转发
requestDispatcher.forward(request,response);
}
- request代表了浏览器发送给服务器的请求报文,该对象由服务器创建并以参数的形式传入到doGet和doPost方法中,在这两个方法中可以直接使用
HttpServletResponse response
- response代表了服务器发送给浏览器的响应报文,该对象由服务器创建并以参数的形式传入到doGet和doPost方法中,在这两个方法中可以直接使用
response的作用
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet方法被调用");
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username);
System.out.println(password);
//response的作用:
//1.给浏览器响应一个字符串或一个页面
/*
响应中文乱码问题的解决方案:
在获取流之前通过response设置响应的内容的类型及字符集UTF-8
*/
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
// writer.write("响应成功!");
// writer.write("<!DOCTYPE html>\n" +
// "<html lang=\"en\">\n" +
// "<head>\n" +
// " <meta charset=\"UTF-8\">\n" +
// " <title>响应页面</title>\n" +
// "</head>\n" +
// "<body>\n" +
// " <h1>我是一个非常漂亮的页面!</h1>\n" +
// "</body>\n" +
// "</html>");
//2.重定向
response.sendRedirect("WEB-INF/success.html");
/*
转发和重定向的区别:
1.转发发送一次请求;重定向发送两次请求
2.转发浏览器地址栏地址无变化;重定向浏览器地址栏地址有变化
3.转发可以访问WEB-INF目录下的资源;重定向不可以访问WEB-INF目录下的资源
4.转发可以共享request域中的数据;重定向不可以共享request域中的数据
*/
}
- response代表了服务器发送给浏览器的响应报文,该对象由服务器创建并以参数的形式传入到doGet和doPost方法中,在这两个方法中可以直接使用
Web中的路径问题
- 在转发的情况下,由于地址栏地址无变化,此时如果用相对路径就有可能导致浏览器解析地址出现异常,所以相对路径不靠谱,建议使用绝对路径
什么是绝对路径?
- 以 / 开头的路径即为绝对路径
- 那么 / 代表什么意思呢:
- 如果路径由浏览器解析,那么 / 就代表当前服务器,即 http://localhost:8080/
- 以下路径由浏览器解析
- 1)html标签中的路径:如img标签、script标签中的src中的路径;a标签、link标签中href中的路径;form标签中action中的路径等
- 2)重定向中的路径
- 1)html标签中的路径:如img标签、script标签中的src中的路径;a标签、link标签中href中的路径;form标签中action中的路径等
- 以下路径由浏览器解析
- 如果路径由服务器解析,那么 / 就代表当前Web应用,即 http://localhost:8080/Web_Servlet_Ex/
- 如果路径由浏览器解析,那么 / 就代表当前服务器,即 http://localhost:8080/
- 以 / 开头的路径即为绝对路径
全称:Java Server Pages,Java的服务页面
- JSP必须要运行在服务器上,不能脱离服务器单独运行
- JSP本质上就是一个Servlet
-
JSP的运行原理
当我们访问jsp页面时会经历以下步骤:
- 1)JSP引擎将jsp页面翻译成java文件
- 2)Java虚拟机将java文件编译成class文件
- 3)Servlet容器根据对应的类创建对象并调用_jspService()方法处理用户的请求
- 1)JSP引擎将jsp页面翻译成java文件
- 以访问index.jsp页面为例:
- 1)JSP引擎将index.jsp页面翻译成index_jsp.java文件
- 2)Java虚拟机将index_jsp.java文件编译成index_jsp.class文件
- 3)Servlet根据index_jsp这个类创建对象并调用_jspService()方法处理用户的请求
- 1)JSP引擎将index.jsp页面翻译成index_jsp.java文件
以后再访问index.jsp页面(前提是没有改变页面中的内容)
JSP脚本片段
- 格式:<% 里面写Java代码 %>
- 作用:JSP脚本片段是用来写Java代码的
- 在JSP页面中可以有多个脚本片段,但是要保证多个脚本片段拼接之后的完整性
<!--JSP的基本语法-->
<%--
1.JSP脚本片段
作用:用来在里面写java代码
--%>
<%
for(int i = 0 ; i < 10 ; i++){
//out.write("今天天气好晴朗,处处好风光!");
%>
<h1>今天天气好晴朗,处处好风光!</h1>
<%
}
%>
- 格式:<% 里面写Java代码 %>
JSP表达式
格式:<%@ 指令名 属性名1=”属性值1” 属性名2=”属性值2” %>
常用的指令
page指令
<%--JSP指令--%>
<%--
1.page指令:用来告诉服务器如何解析当前页面
page指令中的属性:
contentType:告诉浏览器内容的类型以及使用什么字符集进行解码
language:设置编程语言,默认值是java,可选值也是java
pageEncoding:设置当前页面使用的字符集
★errorPage:设置当当前页面出现异常时要转发的页面
isELIgnored:设置是否忽略EL表达式,默认是false,不忽略,通过我们不修改它
★isErrorPage:设置当前页面是否是一个错误页面,默认是false,不是错误页面,
如果改为true,则可用使用exception对象获取异常信息
import:用来导包
--%>
<%
//int a = 10/0;
%>
include指令
<%—2.★include指令:用来将其他页面中的内容包含到当前页面中
file属性:指定要包含的页面的路径
使用include指令实现的包含称为静态包含,静态包含只翻译、编译当前页面,不翻译、编译被包含的页面
—%>
十年修得同船渡
<%@ include file=”/include.jsp”%>
JSP动作标签
- 格式:
- 常用的动作标签
- forward标签
<%--1.★forward标签:用来进行请求的转发
paeg属性:指定要转发的地址
--%>
<%--1)不携带参数的转发,此时开始标签和结束标签中不能有任何内容,否则会抛出异常--%>
<%-- <jsp:forward page="/forward.jsp"></jsp:forward>--%>
<%--2)携带参数的转发
通过param标签携带请求参数:
name属性:指定参数名
value属性:指定参数值
--%>
<jsp:forward page="/forward.jsp">
<jsp:param name="username" value="admin"/>
</jsp:forward>
• include标签
<h1>十年修得同船渡</h1>
<%--2.★include标签:用来将其他页面中的内容包含到当前页面中
page属性:指定要包含的页面的路径
通过include标签实现的包含称为动态包含,动态包含既翻译、编译当前页面,也翻译、编译被包含的页面
什么情况下使用静态包含和动态包含?
如果被包含的页面是一个静态页面,我们通常使用静态包含;
如果被包含的页面是一个动态页面,我们通常使用动态包含
--%>
<jsp:include page="/include.jsp"></jsp:include>
- forward标签
JSP中的九大隐含对象
- JSP的隐含对象即在jsp页面中不用声明就可以直接使用的对象
- JSP的隐含对象之所以可以直接使用是因为在对应的Java类的_jspService()方法中已经声明了这些对象
- 九大隐含对象分别是:
- pageContext
- 类型:PageContext
- 作用:一个顶九个,通过它可以获取其他八个隐含对象
- 它还是一个域对象
- request
- 类型:HttpServletRequest
- 作用:与Servlet中的request的作用一样
- 它还是一个域对象
- session
- 类型:HttpSession
- 在Servlet中通过request.getSession()获取改对象
- 它还是一个域对象
- application
- 类型:ServletContext
- 在Servlet中通过request.getServletContext()获取该对象
- 它还是一个域对象
- response
- 类型:HttpServletResponse
- 作用:与Servlet中的response作用一样
- config
- 类型:ServletConfig
- 作用:获取当前Servlet的配置信息
- out
- 类型:JspWriter
- 作用:与PrintWriter的作用类似,可以向浏览器响应一些数据
- page
- 类型:Object
- 作用:相当于this,代表当前对象(在jsp中几乎不用)
- exception
- 类型:Throwable
- 作用:获取异常信息。前提是jsp页面是一个错误页面,即jsp页面的page指令中的isErrorPage属性值为true
|
| —- |
四个域对象
- 域指区域或者说是范围,在JavaWeb中指不同的Web资源(Servlet、jsp页面)
- 由于不同的Web资源之间需要共享数据,所以就有了域对象
- 四个域对象中都维护着一个Map,用来存、取要共享的数据
- 四个域对象都有以下三个方法:
- void setAttribute(String key , Object value)
- 向域对象中添加属性(设置要共享的数据)
- Object getAttribute(String key)
- 根据属性名从域对象中获取属性值(获取要共享的数据)
- void removeAttribute(String key)
- 根据属性名从域对象中移除属性值
|
| —- |
<%--
Created by IntelliJ IDEA.
User: 韩总
Date: 2020/2/24
Time: 14:03
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>四个域对象</title>
</head>
<body>
<%--
四个域:
page域
范围:当前页面
对应的域对象:pageContext
request域
范围:当前请求(一次请求)
对应的域对象:request
session域
范围:当前会话(一次会话)
对应的域对象:session
application域
范围:当前Web应用
对应的域对象:application
四个域对象都有以下三个方法:
void setAttribute(String key , Object value);
Object getAttribute(String key);
void removeAttribute(String key);
四个域的使用规则:
能用小的就不用大的
Servlet与jsp页面的分工:
Servlet用来处理请求;jsp用来显示数据
--%>
<%--在当前页面分别向四个域中添加四个属性--%>
<%
pageContext.setAttribute("pageKey","pageValue");
request.setAttribute("reqKey","reqValue");
session.setAttribute("sessKey","sessValue");
application.setAttribute("appKey","appValue");
%>
<h1>在当前页面中获取四个域中的属性值</h1>
page域中的属性值是:<%=pageContext.getAttribute("pageKey")%><br>
request域中的属性值是:<%=request.getAttribute("reqKey")%><br>
session域中的属性值是:<%=session.getAttribute("sessKey")%><br>
application域中的属性值是:<%=application.getAttribute("appKey")%><br>
<%--转发到scope2.jsp页面--%>
<%-- <jsp:forward page="/obj/scope2.jsp"></jsp:forward>--%>
<%--通过点击超链接跳转到scope2.jsp页面--%>
<a href="/Web_JSP/obj/scope2.jsp">去scope2.jsp页面</a>
</body>
</html>