Servlet # servlet的入门概述
Posted LRcoding
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet # servlet的入门概述相关的知识,希望对你有一定的参考价值。
1. Servlet
1.1 什么是Servlet?
是⼀个遵循Servlet开发的java类。Servlet是由服务器调⽤的,运⾏在服务器端。
1.2 HTTP协议
超⽂本传输协议(HTTP,HyperText Transfer Protocol)是互联⽹上应⽤最为⼴泛的⼀种⽹络协议。所有的WWW⽂件都必须遵守这个标准。它是TCP/IP协议的⼀个应⽤层协议
HTTP协议就是客户端和服务器交互的⼀种通迅的格式。
HTTP1.0和HTTP1.1的区别
- HTTP1.0协议,客户端与web服务器建⽴连接后,只能获得⼀个web资源【短连接,获取资源后就断开】
- HTTP1.1协议,允许客户端与web服务器建⽴连接后,在⼀个连接上获取多个web资源【保持连接】
1.3 HTTP请求
浏览器向服务器请求某个web资源时,称之为浏览器向服务器发送了⼀个http请求。
http请求应该包含三个部分:
- 请求⾏【描述客户端的请求⽅式、请求的资源名称,以及使⽤的HTTP协议版本号】
- 多个消息头【描述客户端请求哪台主机,以及客户端的⼀些环境信息等】
- ⼀个空⾏
请求行
-
GET:⽤来查询数据,提交速度快,在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。
-
POST:⽤来提交数据,可以在请求的实体内容中向服务器发送数据,传送的数据量⽆限制。
请求头
Accept: text/html,image/* Accept-Encoding: gzip,compress Accept-Charset: ISO-8859-1
1.4 HTTP响应
⼀个HTTP响应代表着服务器向浏览器回送数据
HTTP响应应该包含四个部分:
- ⼀个状态⾏【描述服务器对请求的处理结果。】
- 多个消息头【描述服务器的基本信息以及数据,通过描述信息,可以通知客户端如何处理服务器回送的数据】
- ⼀个空⾏
- 实体内容【服务器向客户端回送的数据】
状态⾏
HTTP版本号 | 状态码 | 原因叙述 |
---|---|---|
HTTP/1.1 | 200 | OK |
404 | 客户端的请求有错误 | |
500 | 服务器有错误 |
响应头
Server:apache tomcat Content-Encoding: gzip Content-Type: text/html; charset=GB2312
2. servlet生命周期
- 加载Servlet。当Tomcat第⼀次访问Servlet的时候,Tomcat会负责创建Servlet的实例
- 初始化。当Servlet被实例化后,Tomcat会调⽤init()⽅法初始化这个对象
- 处理服务。当浏览器访问Servlet的时候,Servlet 会调⽤service()⽅法处理请求
- 销毁。当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会⾃动调⽤**destroy()**⽅法,让该
实例释放掉所占的资源。⼀个Servlet如果⻓时间不被使⽤的话,也会被Tomcat⾃动销毁 - 卸载。当Servlet调⽤完destroy()⽅法后,等待垃圾回收。如果有需要再次使⽤这个Servlet,会重
新调⽤init()⽅法进⾏初始化操作。
-
只要访问Servlet,service()就会被调⽤。
-
init()只有第⼀次访问Servlet的时候才会被调⽤。
-
destroy()只有在Tomcat关闭的时候才会被调⽤。
3. servlet编写
- 继承HttpServlet,重写service方法
public class MyServlet extends HttpServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
String name = req.getParameter("name");
// TODO
}
}
- 配置web.xml文件
4. 细节问题
4.1 servlet细节
4.1.1 ⼀个已经注册的Servlet可以被多次映射
<servlet>
<servlet-name>Demo1</servlet-name>
<servlet-class>lwclick.web.Demo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/Demo1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
4.1.2 Servlet映射的URL可以使⽤通配符
通配符有两种格式:
- *. 扩展名
- 正斜杠(/)开头并以“/*”结尾。
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/*</url-pattern>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
4.1.3 Servlet是单例的
-
Servlet对象⼀旦创建了,就会驻留在内存中,为后续的请求做服务,直到服务器关闭。
-
每次访问请求,都创建新的请求对象(HttpServletRequest)和响应对象(HttpServletResponse)
-
多个⽤户访问Servlet的时候,服务器会为每个⽤户创建⼀个线程。当多个⽤户并发访问Servlet共享资源的时候就会出现线程安全问题。
- 如果⼀个变量需要多个用户共享,则应当在访问该变量的时候,加同步机制synchronized (对象){}
- 如果⼀个变量不需要共享,则直接在service()中定义.这样不会存在线程安全问题
4.1.4 load-on-startup
如果在<servlet>
元素中配置了⼀个<load-on-startup>
元素,那么WEB应⽤程序在启动时,就会装载并创建Servlet的实例对象、以及调⽤Servlet实例对象的init()⽅法。
作用:
- 为web应⽤写⼀个InitServlet,这个servlet配置为启动时装载,为整个web应⽤创建必要的数据库表和数据
- 完成⼀些定时的任务【定时写⽇志,定时备份数据】
4.1.5 在web访问任何资源都是在访问servlet
⽆论在web中访问什么资源【包括JSP】,都是在访问Servlet。
没有⼿⼯配置缺省Servlet的时候,你访问静态图⽚,静态⽹⻚,缺省Servlet会在你web站点中寻找该图⽚或⽹⻚,如果有就返回给浏览器,没有就报404错误
4.2 ServletConfig对象
ServletConfig对象有什么⽤?
通过此对象可以读取web.xml中配置的初始化参数。能够让程序更加灵活【更换需求,更改配置⽂件web.xml即可,程序代码不⽤改】
<servlet>
<servlet-name>Demo1</servlet-name>
<servlet-class>zhongfucheng.web.Demo1</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>zhongfucheng</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/Demo1</url-pattern>
</servlet-mapping>
4.3 ServletContext对象
4.3.1 什么是ServletContext对象?
当Tomcat启动的时候,就会创建⼀个ServletContext对象。它代表着当前web站点
4.3.2 ServletContext有什么⽤?
- ServletContext既然代表着当前web站点,那么所有Servlet都共享着⼀个ServletContext对象,所以Servlet之间可以通过ServletContext实现通讯。
- ServletConfig获取的是配置的是单个Servlet的参数信息,ServletContext可以获取的是配置整个web站点的参数信息
- 利⽤ServletContext读取web站点的资源⽂件
- 实现Servlet的转发【不常用】
4.3.3 Servlet之间实现通讯
ServletContext对象可以被称之为域对象,可以简单理解成⼀个容器【类似于Map集合】
通过serAttribute实现通讯
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();
String value = "lwclick";
//MyName作为关键字,value作为值存进 域对象【类型于Map集合】
servletContext.setAttribute("MyName", value);
//获取ServletContext对象
ServletContext servletContext = this.getServletContext();
//通过关键字获取存储在域对象的值
String value = (String) servletContext.getAttribute("MyName");
System.out.println(value);
4.3.4 获取web站点配置的信息
- web.xml⽂件⽀持对整个站点进⾏配置参数信息【所有Servlet都可以取到该参数信息】
<context-param>
<param-name>name</param-name>
<param-value>lwclick</param-value>
</context-param>
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();
//通过名称获取值
String value = servletContext.getInitParameter("name");
System.out.println(value);
4.3.5 读取资源文件
⽂件放在web⽬录下,直接通过⽂件名称就能获取(web --> WEB-INF --> 资源文件)
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();
//调⽤ServletContext⽅法获取到读取⽂件的流
InputStream inputStream = servletContext.getResourceAsStream("2.png");
5. Response对象
5.1. response、request对象
-
Tomcat收到客户端的http请求,针对每⼀次请求,分别创建⼀个代表请求的request对象和代表响应的response对象
-
获取浏览器提交过来的数据,找request对象
-
向浏览器输出数据,找response对象
HttpServletResponse对象封装了http响应的信息。
5.2. HttpServletResponse的应⽤
5.2.1 调⽤getOutputStream()⽅法向浏览器输出数据
二进制数据
response.setHeader("Content-Type", "text/html;charset=UTF-8");
response.getOutputStream().write("你好呀我是中国".getBytes("UTF-8"));
5.2.2 调⽤getWriter()⽅法向浏览器输出数据
字符数据,不能输出⼆进制数据
response.setContentType("text/html;charset=UTF-8");
//获取到printWriter对象
PrintWriter printWriter = response.getWriter();
printWriter.write("看完博客点赞!");
5.2.3 实现⽂件下载
在web站点下有⼀个图⽚等文件
//获取到资源的路径
String path = this.getServletContext().getRealPath("/download/1.png");
//读取资源
FileInputStream fis = new FileInputStream(path);
//获取到⽂件名,路径在电脑上保存是\\\\形式的。
String fileName = path.substring(path.lastIndexOf("\\\\") + 1);
//设置消息头,告诉浏览器,我要下载1.png这个图⽚
response.setHeader("Content-Disposition", "attachment; filename="+URLEncoder.encode(fileName, "UTF-8")););
//把读取到的资源写给浏览器
int len = 0;
byte[] bytes = new byte[1024];
ServletOutputStream sos = response.getOutputStream();
while ((len = fis.read(bytes)) > 0) {
sos.write(bytes, 0, len);
}
//关闭资源
servletOutputStream.close();
fileInputStream.close();
5.2.4 实现自动刷新
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("3秒后跳转⻚⾯.....");
//三秒后跳转到index.jsp⻚⾯去,web应⽤的映射路径我设置成/,url没有写上应⽤名
response.setHeader("Refresh", "3;url='/index.jsp'");
5.2.5 设置缓存
【浏览器默认有缓存,对于需要实时更新的数据,取消缓存】
//浏览器有三消息头设置缓存,为了兼容性!将三个消息头都设置了
response.setDateHeader("Expires", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
5.2.6 实现数据压缩
GZIP类来对数据压缩,把压缩后的数据取出来,写给浏览器
5.2.7 生成随机图⽚
//在内存中⽣成⼀张图⽚,宽为80,⾼为20,类型是RGB
BufferedImage bImg = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//获取到这张图⽚
Graphics g = bImg.getGraphics();
//往图⽚设置颜⾊和字体
g.setColor(Color.white);
g.fillRect(0, 0, 80, 20);
g.setFont(new Font(null, Font.BOLD, 20));
//往图⽚上写数据,先写个12345,横坐标是0,纵坐标是20【⾼度】
graphics.drawString("12345", 0, 20);
//要往浏览器写⼀张图⽚,那要告诉浏览器回送的类型是⼀张图⽚
response.setHeader("ContentType", "jpeg");
//java提供了图⽚流给我们使⽤,这是⼀个⼯具类
//把图⽚传进去,类型是jpg,写给浏览器
ImageIO.write(bImg, "jpg", response.getOutputStream());
private String makeNum() {
Random random = new Random();
//这样就会⽣成0-7位的随机数,如果不够7位,我们加到7位就⾏了
int anInt = random.nextInt(9999999);
//将数字转成是字符串
String num = String.valueOf(anInt);
//判断位数有多少个,不够就加
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 7 - num.length(); i++) {
stringBuffer.append("0");
}
return stringBuffer.append(num).toString();
}
5.2.8 重定向跳转
点击⼀个超链接,通知浏览器跳转到另外的⼀个⻚⾯就叫重定向跳转。
//重定向到index.jsp⻚⾯
response.sendRedirect("/lwclick/index.jsp");
重定向是通过302状态码和跳转地址实现的
6. Request对象
6.1. 什么是HttpServletRequest
客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发⼈员通过这个对象的⽅法,可以获得客户这些信息。
6.2. 常用方法
- getRequestURL 返回客户端发出请求时的完整URL
- getQueryString 返回请求⾏中的参数部分
- getRemoteAddr 返回发出请求的客户机的IP地址
- getLocalAddr 返回WEB服务器的IP地址
- getHeader 获得客户机请求头
- getParameter 获得客户机请求参数(客户端提交的数据)
6.3. 应用
6.3.1 防盗链
不能使用复制粘贴网址,拿走网站上的资源
//获取到⽹⻚是从哪⾥来的
String referer = request.getHeader("Referer");
//如果不是从我的⾸⻚来或者从地址栏直接访问的,
if ( referer == null || !referer.contains("localhost:8080/lwclick/index.jsp") ) {
//回到⾸⻚去
response.sendRedirect("/lwclick/index.jsp");
return;
}
//能执⾏下⾯的语句,说明是从我的⾸⻚点击进来的,那没问题,照常显示
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("路⻜做了xx");
6.3.2 表单提交数据【通过post⽅式提交数据】
点击提交按钮的时候,数据封装进了FormData中
http请求中把实体主体带过去了【传输的数据称之为实体主体】
既然request对象封装了http请求,所以request对象可以解析到发送过来的数据
于是只要把编码设置成UTF-8就可以解决乱码问题了。
<form action="/lwclick/formServlet" method="post">
<table>
<tr><td>⽤户名</td>
<td><input type="text" name="username"></td></tr>
<tr><td>密码</td>
<td><input type="password" name="password"></td></tr>
<tr><td>性别</td>
<td>
<input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="⼥">⼥
</td></tr>
<tr><td>爱好</td>
<td>
<input type="checkbox" name="hobbies" value="游泳">游泳
<input type="checkbox" name="hobbies" value="跑步">跑步
<input type="checkbox" name="hobbies" value="⻜翔">⻜翔
</td></tr>
<input type="hidden" name="aaa" value="my name is lwclick">
<tr><td>你的来⾃于哪⾥</td>
<td>
<select name="address">
<option value="⼴州">⼴州</option>
<option value="深圳">深圳</option>
<option value="北京">北京</option>
</select>
</td></tr>
<tr><td>详细说明:</td>
<td>
<textarea cols="30" rows="2" name="textarea"></textarea>
</td></tr>
<tr>
<td><input type="submit" value="提交"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
在formServlet获取值
//设置request字符编码的格式
request.setCharacterEncoding("UTF-8");
//通过html的name属性,获取到值
String username = request.getParameter("username");
String password = request.getParameter("password");
String gender = request.getParameter("gender");
//复选框和下拉框有多个值,获取到多个值
String[] hobbies = request.getParameterValues("hobbies");
String[] address = request.getParameterValues("address");
//获取到⽂本域的值
String description = request.getParameter("textarea");
//得到隐藏域的值
String hiddenValue = request.getParameter("aaa");
....各种System.out.println().......
6.3.3 超链接⽅式提交数据(get方式) – 不推荐
get⽅式不同,它的数据是从消息⾏带过去的,没有封装到request对象⾥⾯
<a href="/lwclick/formServlet?username=xxx">使⽤超链接将数据带给浏览器</a以上是关于Servlet # servlet的入门概述的主要内容,如果未能解决你的问题,请参考以下文章