Servlet
概念:服务器端小程序
作用:1)请求处理 2)返回响应
运行环境:Tomcat (apache) 8.5 支持servlet 3.1
Tomcat: 目录结构
bin 脚本目录 startup.bat shutdown.bat(ctrl+C)
conf 配置目录 默认端口8080, server.xml 搜索8080 然后修改
logs 日志目录
webapps 应用程序目录
编写servlet
java类继承 HttpServlet
在servlet类上添加注解 @WebServlet(urlPatterns="/servlet路径")
http://ip地址:8080/servlet路径?参数名=参数值(get请求)
重写(覆盖)
```
public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException ,IOException
{
//1.处理请求
request.setCharacterEncoding("utf-8");//设置字符编码
request.getParameter("参数名"); //返回参数值String
//2返回响应
response.setContentType("text/html;charaset=utf-8");//设置字符编码
PrintWriter w=response.getWriter();//拿到字符输出流
w.println("html代码");
}
```
1.servlet 的生命周期
浏览器首次向servlet发送请求,会创建它的实例对象;以后再发送请求使用的仍然是第一次创建的对象。
结论:整个生命周期中,servlet只有一个实例(单例的)
1)构造方法首次执行(只执行一次)
2)初始化方法 init(只执行一次)
3)服务方法 service(反复被执行)来一次请求执行一次
4)销毁方法 destroy (只执行一次)在服务器停止前
2doGet与doPost
覆盖service方法,可以处理所有类型的请求
覆盖doGet方法,可以处理get方式的请求
覆盖doPost方法,可以处理post方式的请求
3一个Java web项目
|-
|-WEB-INF (受保护不能直接访问)
|-classes 放自己编写的Java类
|-lib 放第三方的jar包
|-css 放样式表
|-js 放js脚本
|-jsp 放网页文件
|-index。jsp 首页面 如果没有写具体的地址,会按index.html, index.jsp
注意:在一个项目内,多个urlPatterns不能重复,要确保唯一
使用servlet生成HTML标签,代码难以维护,可读性差,容易出错
4jsp
Java server page
用途:主要用来生成HTML标签
在表现形式上类似于html 但多了一行
```
<%@ page contentTypt=text/html;charaset="utf-8"%>
```
上面代码成为page指令,主要作用就是指明此页面是一个jsp页面,并且通过contextType说明他的字符编码和格式。
jsp中有
1.指令: `<% 指令名%>`
2.脚本: `<% 可以是任意的Java代码%>`
3.表达式:`<%=%>`将执行的结果显示在页面
4EL表达式语音
expression language 在jsp用来展示结果的语音
语法
`${表达式语言}`
要用 el表达式显示复杂的的内容,需要把内容提前放入`作用域`,el再从`作用域`把内容取出来显示
//设置属性
pagaContext.setAttribute("名称",Object);//把内容起一个名字放入作用域之后就可以通过EL表达式
${pageScope.名称}
el表达式可以通过
${对象.属性名} 但这里的属性名,依据是对象的get方法,而不是私有属性名
把get方法中get去掉(或 把is方法的is去掉),剩余的单词首字母小写作为对象的属性名,例如
getName()==>name
getUsername()==>username
isClose()==>close()
6 jstl
java 标准标签库
Java standard tag library
主要的工具就是配合el表达式,实现循环,条件判断等功能
前提:加入jstl-1.2的jar包
导入标签库
<%@ taglib uri="标签库唯一标识" prefix="前缀"%>
6.1 forEach
```
<c:forEach items="要遍历的集合" var="临时变量名" begin="起始数字" end="结束数字">
${临时变量名}
</c:>
```
要遍历集合 必须使用${}从作用域中取值
6.2 if
```
<c:if test="布尔表达式">内容</c:if>
```
7.MVC思想
Model 模型==》数据(例如从数据库查询出来的list集合,里面包含Java对象)
View 视图==>数据的展现形式(jsp就是一种视图技术)
Controller 控制器==>把模型和视图联系起来(servlet 充当控制器作用)
由servlet器查询数据,把查询出来的数据放入作用域,跳转至jsp视图
jsp视图从作用域中获取数据,并显示
服务器常见的错误leix
500 Internet Server Error 服务器内部错误,用于应用程序自己没有正确处理异常,异常抛给Tomcat 这时就会出现500
404 Not Found 资源未找到错误,发生于要访问的资源不存在(资源可能是servlet jsp HTML)
405 Method Not Allowed 方法不支持
当没有覆盖doGet方法,但发送了get请求时
当没有覆盖doPost方法,但发送了post请求时
200 OK表示这次请求正常,没有发生错误
304 这个文件没有修改,请浏览器使用上一次缓存的文件
这些数字成为响应状态码
8:jstl标签
c:chose 类似于 if elseif else
语法:
```
<c:choose>
<c:when test="条件1">内容1</c:when>
<c:when test="条件2">内容2</c:when>
...
<c:when test="条件n">内容n</c:when>
<c:otherwise>以上条件都不成立时</c:otherwise>
</c:choose>
```
c:out 用来输出特殊内容
它可以对${}输出的内容进行控制,可以控制是否忽略HTML代码
```
<c:out escapeXML="false" value="作用域变量">不忽略HTML代码
```
```
<c:out escapeXML="true" value="作用域变量">忽略Html,(当做普通文本)
```
fmt:fotmatDate用来格式化日期
fmt:formatNumber 用来格式化数字
语法示例
```
<fmt:formatData value="日期对象" pattern="日期格式"></fmt:formatDate>
<fmt:formatNumber value="数字对象" pattern="数字格式"></fmt:formatNumber>
```
数字格式`#`和`0` 其中0可以用来前置补零或后置补零
**9 jsp 遗留语法**
9.1 jsp的脚本
```
<%
任意的Java代码
%>
```
jsp的弊端在于当代码越来越多时,使用jsp脚本的方式,会造成项目代码难以维护
现在绝大数公司都禁止在jsp出现脚本代码
9.2 jsp 表达式
```
<%=表达式%>
```
作用向页面显示值。表达式不能以`;`结束
9.3jsp指令
```
<%@ page contextType="页面的内容类型和编码"\
import="要导入的Java类"
isELIgnore="是否忽略EL表达式的处理"
errorPage="出现错误时要跳转的页面"
isErrorPage="用在错误页面上。取值为true表示是错误页面,这时候才能在页面中使用exception变量"
%>
```
exception 只能配合jsp表达式和jsp脚本使用
```
<%@ taglib prefix="前缀" uri="页面的唯一标识"%>
```
作用是导入标签库
```
<%@ include file="另一个页面"%>
```
作用,重用页面的一些标签和代码
9.4jsp声明
```
<%!
可以声明变量和方法
%>
```
jsp 要工作,也必须编译为Java类
```
public class 类名 extends HttpJspBase {
public int i=100;
public int sum(int a,int b){
return a+b;
}
public void _jspService(HttpServletRequest request HttpServletResponse response){
int i=10;
out.println(i)
}
}
```
1)当首次访问此jsp时,Tomcat会把jsp转译为*.java的类(间接继承自HttpServlet)
2)再把*.java类编译为*.class字节码
3)把加载到虚拟机执行,生命周期类似于servlet的生命周期
jsp的本质仍是一个servlet
9.5 9大隐式对象
无需声明即可用
request 代表请求对象(可以获取请求参数,将变量存入request作用域)
response 代表响应(返回响应)
out 代表字符输出流
pageContext 页面上下文对象,可以间接获得request等对象,可以将变量存入page作用域
config jsp的配置信息
page 当前jsp对象(this)
exception 代表异常信息(当页面isErrorPage="true"时有效)
session 变量作用范围是一次会话内有效
application 变量作用范围是整个应用程序有效
page作用域 变量作用范围仅限与当前页面
request作用域 变量作用范围再一次请求内有效
5.jsp forward 6.jsp 两个页面使用的是同一个请求
servlet
servlet forward x.jsp servlet和jsp使用的是同一个请求
http协议的特点:称之为`无状态`,请求与请求之间不会记录状态(状态就包括请求参数等)
1.Cookie
本意是小甜点,可以用来记录多个请求之间的联系,保存服务的状态
实现记住一个用户名的功能
1.1 创建Cookie
Cookie c=new Cookie("名字","值");//创建Cookie
c.setMaxAge(整数);//设置Cookie的寿命,单位是秒,没有设置寿命的是会话cookie浏览器就删除
c.setMaxAge(0); 设置寿命为0,就意味着删除此cookie
response.addCookie(c);//通过响应对象,把创建的cookie返回给浏览器
浏览器每次发送请求时,就会根据域名进行检查,把该域名下的所有cookie发给服务器
1.2获取cookie
Cookie [] cookies=request.getCookies();//获取请求中的所有cookie
1.3中文问题
URLEncoder.encode("中文","utf-8");//将编码后的中文存入cookied的值
URLDecoder.decode("编码后的内容","utf-8");//把编码后的内容进行解码
1.4 el表达式获取cookie的值
el 语法
${cookie.cookie的名称.value}
1.5 cookie 的限制
浏览器每个域名下能够包含30-50个cookie、
每个cookie的长度大约是4k左右
2session会话
session也是用来存储多次请求之间的状态信息,session是把这些信息存储在服务器的内容当中
2.1session 创建
HTTPSession session=request.getSession();
//首次调用getSession方法就是创建session对象
//后续在调用getSession方法是获取第一次创建的session对象
存入内容
session.setAttribute("变量名",任意信息);
获取内容
Object 信息=session.getAttribute("变量名");
删除内容
session.removeAttribute();
让session失效,(会清空session中所有的内容)
session.invalidate();
jsp页面获取session中的变量
${sessionScope.变量名}
session 实现的原理
session 必须针对同一个浏览器,才能实现在请求存储信息、在之后的请求获取信息的效果
每个用户访问服务器时,服务器会为他们创建一个独立的session
1)首次创建session时,Tomcat会产生一个名为 `JSESSIONID=session的唯一标识 ` 的特殊cookie
这个 `JSESSIONID=1` 就会随着响应返回给浏览器
2)浏览器会记录这个cookie。之后的所有请求会把此cookie发送给服务器
服务器会根据cookie的值找到对应的session
3)jsessionid 这个cookie属于会话cookie,浏览器关闭就会消失
对比cookie和session
1)session是将信息存储在服务器端,cookie是将信息存储于浏览器端
2)session于cookie相比,更为安全
3)session的生命周期较短,两次请求间隔超过30分钟,服务器会销毁session
调用session.invalidate 方法时,会立刻销毁
cookie 会话cookie是浏览器关闭就销毁
setMaxage的cookie会根据设置的寿命存活一段时间
4)信息的存储量上
cookie 每个最大大小是4k左右
session理论上没有限制,但session要占据服务器内存,所有不太适合存储太多的内容
信息要永久存储,还是需要使用数据库
5)cookie里数据都是字符串,而session里可以存储任意类型
3重定向请求
转发请求
request.getRequestDispatcher("目录路径").forward(request,response)
请求重定向
response.sendRedirect("目录路径");
区别
1)请求转发时,地址栏不会变(是第一个servlet的地址)
重定向,地址栏会发生变化(是最后一个servlet的地址)
2)请求转发是一次请求。跳转发生在服务器内部
重定向是两次请求,第一次请求会返回302的状态码和目标地址
浏览器根据目标址发送第二次请求,才完成整个流程
3)重定向是两次请求,所以不能用request作用域存取值
但可以使用session作用域来存取值
请求转发是同一次请求,所以可以使用request作用域来存取值
4)请求转发的目标只能是本项目的servlet或jsp
重定向跳转的目标可以是任意的