服务器端——Servlet

服务器Servlet

 

 

本篇三部分: 

一、web开发入门 (http协议)

二、Servlet和ServletConfig

三、request、response

四、cookie、session

 

 

一、web开发

 1.web开发先看看有哪些web 相关技术: 

静态web技术:html

动态web技术:JSP/Servlet、ASP、PHP

 2.web资源访问流程:

文字概述:

1.询问本机window中host得到网址IP 2.没有从host中得到的话就会再从DNS解析域名成IP 3.得到IP后连接网站服务器端 4.连接后发送http请求 5.服务器从http请求中得到客户机想要访问的主机名以及想访问的应用和资源 6.从而读取相应主机的web应用和web资源 (得到html) 7.读取资源并回应http响应到服务器端 8.服务器端发送http响应至浏览器 9.浏览器解析响应

图解:  (补充: DNS:解析域名成IP地址。 TCP协议:验证传输 。IP协议:地址)

3.http协议:

(1)概述:

          http:是超文本传输协议  ,是TCP/IP协议上的应用层协议

         a. 用于定义web浏览器与web服务器间的交换数据的过程。客户端和服务器交互的一种通迅的格式

         b.HTTP是无状态的,也就是说,它是不对通信状态进行保存的。它并不知道之前通信的对方是谁。这样设计的目的就是为了让HTTP简单化,能够快速处理大量的事务!

         c.一次HTTP连接能够处理多个请求。在一次HTTP连接里面,不需要等待服务器响应请求,就能够继续发送第二次请求。

         d.常用的HTTP方法 post/get(请求方式有:POST,GET,HEAD,OPTIONS,DELETE,TRACE,PUT

 

(2)http请求

格式: a.请求行 (GET是默认方式,加?会在连接上显示数据,但get方式带的容量有限不能超过1K,而post方式无限量

         b.多个请求头(host,cookie,,,)

         c.空行

         d.请求数据

 

(3)http响应

代表服务器向客户端回送的数据       

       格式: 状态行  (有状态码)

                  多个响应头

                  一个空行

                  实体

 

(4).常用的状态码

2XX :一般是请求成功 200 正常处理 204 成功处理,但服务器没有新数据返回,显示页面不更新 206 对服务器进行范围请求,只返回一部分数据

3XX :一般表示重定向 301 请求的资源已分配了新的URI中,URL地址改变了。【永久重定向】 302 请求的资源临时分配了新的URI中,URL地址没变【转发】 303 与302相同的功能,但明确客户端应该采用GET方式来获取资源 304 发送了附带请求,但不符合条件【返回未过期的缓存数据】 307 与302相同,但不会把POST请求变成GET

4XX :表示客户端出错了。 400 请求报文语法错误了 401 需要认证身份 403 没有权限访问 404 服务器没有这个资源

5XX :服务器出错了 500 内部资源出错了 503 服务器正忙

 

(5).Https:

 https: http是不安全的,使用SSL建立安全的通信线路,HTTPS就是披着SSL的HTTP。

Http与Https的区别

(1)写法:HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头

(2)安全性:HTTP 是不安全的,而 HTTPS 是安全的

(3)端口:HTTP 标准端口是80 ,而 HTTPS 的标准端口是443

(4)工作层:在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层

(5)加密性:HTTP 无法加密,而HTTPS 对传输的数据进行加密

(6)证书:HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书

 

(6).URI和URL的区别

URI:是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。它唯一的作用就是解析

URL:是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。URL类可以打开一个到达资源的流。

 

 

二、Servlet和ServletConfig

1.Servlet

(1)作用

 Servlet:动态WEB技术,就是能够处理浏览器带来HTTP请求,并返回一个响应给浏览器,从而实现浏览器和服务器的交互

(2)servlet线程安全问题

是不安全的。

线程安全问题 当多个用户访问Servlet的时候,服务器会为每个用户创建一个线程。当多个用户并发访问Servlet共享资源的时候就会出现线程安全问题。

 (3)生命周期

  1. 加载Servlet。当Tomcat第一次访问Servlet的时候,Tomcat会负责创建Servlet的实例
  2. 初始化。当Servlet被实例化后,Tomcat会调用init()方法初始化这个对象
  3. 处理服务。当浏览器访问Servlet的时候,Servlet 会调用service()方法处理请求
  4. 销毁。当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用destroy()方法,让该实例释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁
  5. 卸载。当Servlet调用完destroy()方法后,等待垃圾回收。如果有需要再次使用这个Servlet,会重新调用init()方法进行初始化操作
  • 简单总结:**只要访问Servlet,service()就会被调用。init()只有第一次访问Servlet的时候才会被调用。

(4)

为什么Servlet是单例

浏览器多次对Servlet的请求,一般情况下,服务器只创建一个Servlet对象,也就是说,Servlet对象一旦创建了,就会驻留在内存中,为后续的请求做服务,直到服务器关闭

(5)

线程安全问题

当多个用户访问Servlet的时候,服务器会为每个用户创建一个线程当多个用户并发访问Servlet共享资源的时候就会出现线程安全问题

原则:

  1. 如果一个变量需要多个用户共享,则应当在访问该变量的时候,加同步机制synchronized (对象){}
  2. 如果一个变量不需要共享,则直接在 doGet() 或者 doPost()定义.这样不会存在线程安全问题

(6)缺省Servlet

 

 

2.ServletConfig

通过此对象可以读取web.xml中配置的初始化参数。

(1)获取方法:   

this.getServletContext();

 

3.ServletContext 域 

   全局域对象 代表着当前web站点    (一个容器

获取:ServletContext context= (ServletContext) this.getServletContext();

 

作用:ServletContext可以获取的是配置整个web站点的参数信息 所有Servlet都共享着一个ServletContext对象,所以Servlet之间可以通过ServletContext实现通讯。 实现servlet的转发 利用servletContext对象读取资源文件。

 

方法:ServletContext的setAttribute(String name,Object obj)方法

 //获取到ServletContext对象
        ServletContext servletContext = this.getServletContext();
        String value = "zhongfucheng";
        //MyName作为关键字,value作为值存进 域对象【类型于Map集合】 servletContext.setAttribute("MyName", value);

 

4.HttpServlet类

处理HTTP请求的servlet

 实现HttpServlet

 

三、request、response

什么是HttpServletResponse对象

http响应由状态行、实体内容、消息头、一个空行组成。HttpServletResponse对象就封装了http响应的信息。

 

 

  1.response 应用案例

向浏览器输出数据,找response对象

    (1)response写出数据:

response.setContentType("text/html;charset=UTF-8");

//获取到printWriter对象
PrintWriter printWriter = response.getWriter();
printWriter.write("看完博客点赞!");

 

 (2)response实现下载文件

String path= this.getServletContext().getRealPath("/download/环奈.jpg");
//截取文件名方法 substring(path.lastIndexOf("\\")+1)
String filename =path.substring(path.lastIndexOf("\\")+1);
//打开方式
response.setHeader("content-disposition", "attachment;filename"+URLEncoder.encode(filename,"UTF-8"));
//这两行代码作用就是为了提供给下载功能,去掉后则直接是显示图片
//通过流写数据
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(path);
int len = 0;
byte[] buffer = new byte[1024];
out = response.getOutputStream();//修改
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

 

(3)servlet方法的验证码 ,随机生成图片

BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_RGB);
Graphics g=image.getGraphics();
//1.设置背景色
setBackGround(g);
//2.设置边框
setBorder(g);
//3.设置干扰线
drawRandomLine(g);
//4.写随机数
drawRandomNum(g);
//5.图形写给浏览器
response.setContentType("image/jpeg");
//去掉缓存,即更新
response.setHeader("Cache-Content", "no-cache");
response.setHeader("Pragma", "no-cache");
ImageIO.write(image, "jpg", response.getOutputStream());
}
//设置背景色
private void setBackGround(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, WIDTH, HEIGHT);
}
//设置边框
private void setBorder(Graphics g) {
g.setColor(Color.BLUE);
g.drawRect(1, 1, WIDTH-2, HEIGHT-2);
}
//设置干扰线
private void drawRandomLine(Graphics g) {
g.setColor(Color.GREEN);
for(int i=0;i<5;i++){ //设置五条干扰线
int x1=new Random().nextInt(WIDTH);
int y1=new Random().nextInt(HEIGHT);
int x2=new Random().nextInt(WIDTH);
int y2=new Random().nextInt(HEIGHT);
g.drawLine(x1, y1, x2, y2); //做线
}
}
//写随机数
private void drawRandomNum(Graphics g) {
g.setColor(Color.RED);
g.setFont(new Font("宋体",Font.BOLD,20));
String base="\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a";
StringBuffer sb=new StringBuffer();
int x=0;
for(int i=0;i<4;i++){
int degree=new Random().nextInt(30);
String ch=base.charAt(new Random().nextInt(base.length()))+"";
sb.append(ch);
// // 写入字之前,设置好旋转
// g.rotate(degree*Math.PI/180, x, 20); // 设置字体旋转角度
// g.drawString(ch, x, 20);
// // 这次旋转不能影响下一次的旋转,所以要将上一次的旋转清掉,转回去
g.drawString(ch, x, 30);
x+=50;
}
}

 

(4).定时刷新,转发

response.setContentType("text/html;charset=UTF-8");

response.getWriter().write("3秒后跳转页面....."); //三秒后跳转到index.jsp页面去,web应用的映射路径我设置成/,url没有写上应用名

response.setHeader("Refresh", "3;url='/index.jsp'");

(5)response 请求重定向
例如:response.sendRedirect("/WEB2/index.jsp");

 

 

 

2.request 应用案例

获取浏览器提交过来的数据,找request对象

(1)HttpServletRequest:

要得到浏览器信息,就找HttpServletRequest对象

HttpServletRequest常用方法


.获得客户机【浏览器】信息
getRequestURL方法返回客户端发出请求时的完整URL。
getRequestURI方法返回请求行中的资源名部分。
getQueryString 方法返回请求行中的参数部分。
getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
getRemoteAddr方法返回发出请求的客户机的IP地址
getRemoteHost方法返回发出请求的客户机的完整主机名
getRemotePort方法返回客户机所使用的网络端口号
getLocalAddr方法返回WEB服务器的IP地址。
getLocalName方法返回WEB服务器的主机名

 

.获得客户机请求头
getHeader方法
getHeaders方法
getHeaderNames方法

 

.获得客户机请求参数(客户端提交的数据)
getParameter方法
getParameterValues(String name)方法
getParameterNames方法
getParameterMap方法

 

(2) request转发

使用response的sendRedirect()可以实现重定向,做到的功能是页面跳转,
使用request的getRequestDispatcher.forward(request,response)实现转发,做到的功能也是页面跳转

 

//获取到requestDispatcher对象,跳转到index.jsp

RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.jsp");

//调用requestDispatcher对象的forward()实现转发,传入request和response方法

requestDispatcher.forward(request, response);

(3)中文乱码

post方式直接改request对象的编码
get方式需要手工转换编码
get方式也可以修改Tomcat服务器的编码,不推荐,因为会太依赖服务器了!
提交数据能用post就用post

 request.setCharacterEncoding("UTF-8");

 

(4)防盗链(设计网投、网尾)

例子:
//获取到网页是从哪里来的
String referer = request.getHeader("Referer");
//如果不是从我的首页来或者从地址栏直接访问的,
if ( referer == null || !referer.contains("localhost:8080/zhongfucheng/index.jsp") ) {
//回到首页去
response.sendRedirect("/zhongfucheng/index.jsp");
return;
}
//能执行下面的语句,说明是从我的首页点击进来的,那没问题,照常显示
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("路飞做了XXXXxxxxxxxxxxxxxxxx");

 

3.补充

(1)转发和重定向的区别

实际发生位置不同,地址栏不同

 

转发是发生在服务器的,
实现转发只是一次的http请求,一次转发中request和response对象都是同一个。这也解释了,为什么可以使用request作为域对象进行Servlet之间的通讯。

重定向是发生在浏览器的
重定向是由浏览器进行跳转的,进行重定向跳转的时候,浏览器的地址会发生变化的。曾经介绍过:实现重定向的原理是由response的状态码和Location头组合而实现的。
这是由浏览器进行的页面跳转实现重定向会发出两个http请求,**request域对象是无效的,因为它不是同一个request对象

 

用法不同:
给服务器用的直接从资源名开始写,给浏览器用的要把应用名写上
request.getRequestDispatcher("/资源名 URI").forward(request,response)

转发时"/"代表的是本应用程序的根目录


response.send("/web应用/资源名 URI");
重定向时"/"代表的是webapps目录

 

典型的应用场景:

转发: 访问 Servlet 处理业务逻辑,然后 forward 到 jsp 显示处理结果,浏览器里 URL 不变
重定向: 提交表单,处理成功后 redirect 到另一个 jsp,防止表单重复提交,浏览器里 URL 变了

 

重定向特点:

1.浏览器会向服务器发送两次,意味这有两个request/response
2.重定向技术会让浏览器地址发生变化
3.response 中getOutStream()和getWrite()不能同时用

 

重定向与请求转发使用

前后两个页面 有数据传递 用请求转发,没有则用重定向。 

 

重定向时的网址可以是任何网址

  转发的网址必须是本站点的网址

 

 

 

四、cookie、session

会话:访问一个网站,只要不关闭该浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,整个这个过程我们称为一次会话.

 

保存会话数据的两种技术:
Cookie 客户端技术
Sesssion 服务端技术

 

区别:
cookie是把用户的数据写给用户的浏览器
session技术是把用户的数据写到用户独占的seesion中

 

 

 

1.Cookie
流程:浏览器访问服务器,如果服务器需要记录该用户的状态,就使用response向浏览器发送一个Cookie,浏览器会把Cookie保存起来。
当浏览器再次访问服务器的时候,浏览器会把请求的网址连同Cookie一同交给服务器。

 

常用的Cookie方法:
public Cookie(String name,String value)
setValue与getValue方法
setMaxAge与getMaxAge方法
setPath与getPath方法
setDomain与getDomain方法
getName方法

 

2.设置时间  

没有设置有效期那么浏览器关闭cookie数据消     ,不设置时间不会显示cookie文本

Cookie的有效期是通过setMaxAge()来设置的。cookie.setMaxAge(1000);

如果MaxAge为正数,浏览器会把Cookie写到硬盘中,只要还在MaxAge秒之前,登陆网站时该Cookie就有效【不论关闭了浏览器还是电脑】
如果MaxAge为负数,**Cookie是临时性的,仅在本浏览器内有效,关闭浏览器Cookie就失效了,Cookie不会写到硬盘中。Cookie默认值就是-1。

如果MaxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie对应的方法,把MaxAge设置为0等同于删除Cookie

 

案例:
response.setContentType("text/html;charset=UTF-8");
PrintWriter printWriter = response.getWriter();
String name = "看完博客就点赞";
//对Unicode字符进行编码
Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));
//一定不要忘记添加到浏览器中
cookie.setMaxAge(0);
response.addCookie(cookie);
printWriter.write("我删除了该Cookie");

 

 3.每个cookie的大小限制为4kB

 

4.Cookie具有不可跨域名性:所以一般来说,当我访问baidu的时候,浏览器只会把baidu颁发的Cookie带过去,而不会带上google的Cookie。

 

5.显示上次时间

案例:

// 防止乱码
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");

// 建立输出流
PrintWriter out = response.getWriter();
out.print("上次访问时间: <br/>");

// 获取COOKIE时间
Cookie[] cookies = request.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
if (cookies[i].getName().equals("lastAccessTime")) {
long cookiesvalue = Long.parseLong(cookies[i].getValue());

Date date = new Date(cookiesvalue);
out.print(date.toLocaleString());
}
}
// 数据发送到浏览器并设置
Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()
+ "");
cookie.setMaxAge(1 * 30 * 24 * 3600);
cookie.setPath("/WEB3");
response.addCookie(cookie);

 

2.Sesssion

 一个浏览器独占一个session对象

 session由服务器创建,开发人员调用request对象的getsession方法得到session对象

 Session比Cookie使用方便,Session可以解决Cookie解决不了的事情   :Session可以存储对象,Cookie只能存储字符串

周期: 创建session,不管浏览器是否关闭,在三十分钟后自动摧毁session。

session原理:request.getSession()方法创建session,同时生成sessionId,cokkie带sessionId返回浏览器保存,下次浏览器访问时根据id调用对应的seesion
(所以说sessin是基于cookie)

 

1.Session API:

long getCreationTime();【获取Session被创建时间】
String getId();【获取Session的id】
long getLastAccessedTime();【返回Session最后活跃的时间】
ServletContext getServletContext();【获取ServletContext对象】
void setMaxInactiveInterval(int var1);【设置Session超时时间】
int getMaxInactiveInterval();【获取Session超时时间】
Object getAttribute(String var1);【获取Session属性】
Enumeration
getAttributeNames();【获取Session所有的属性名】
void setAttribute(String var1, Object var2);【设置Session属性】
void removeAttribute(String var1);【移除Session属性】
void invalidate();【销毁该Session】
boolean isNew();【该Session是否为新的】

 

2.案例1:用户登录

3.案例2:防止表单重复提交

 4.当禁用cookie时,用URL重写实现session

URL地址重写的原理:将Session的id信息重写到URL地址中。服务器解析重写后URL,获取Session的id。这样一来,即使浏览器禁用掉了Cookie,但Session的id通过服务器端传递,还是可以使用Session来记录用户的状态。

 

 

Session和Cookie的区别

1.存储方式上比较
Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码。
Session可以存储任何类型的数据,可以把Session看成是一个容器

2.从隐私安全上比较
Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密
Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题

3.从对服务器的负担比较
Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。
Cookie是保存在客户端的。不占用服务器的资源。像baidu、Sina这样的大型网站,一般都是使用Cookie来进行会话跟踪

4.从跨域名上比较
Cookie可以设置domain属性来实现跨域名
Session只在当前的域名内有效,不可夸域名

 5.cookie是吧数据写到浏览器

    session是把数据写到用户独立的session中

 

 


(*)四个域对象
session(session域)、servletContext(application域)、request(reqeust域)、pageContext(page域)

request容器:当程序产生数据后如果显示后没有用了就用requst,一次请求
session:产生数据后除了显示等一会要用到则session,一次会话
servletContext:不仅等一会还要给别人用(例如聊天室),整个web应用
pageContext(page域):当前Jsp页面范围

 

转载于:https://www.cnblogs.com/StingLon/p/9816694.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值