My-Blog-Hexo/source/_posts/一文搞懂java-Servlet.md
2024-12-18 20:27:43 +08:00

19 KiB
Raw Blame History

title date tags categories
一文搞懂java Servlet 2020-12-12 13:49:39
JavaWeb
servlet
session
cookie
JavaWeb

servlet简介

ServletServer Applet全称Java Servlet是用Java编写的运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。其主要功能在于交互式地浏览和修改数据生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口广义Servlet是指任何实现了这个Servlet接口的类一般情况下人们将Servlet理解为后者。

下图显示了 Servlet 在 Web 应用程序中的位置。

Servlet工作模式

① 客户端发送请求至服务器

  • 这些请求可以是显式的数据,包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单
  • 也可以是隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。

② 服务器启动并调用ServletServlet根据客户端请求生成响应内容并将其传给服务器

③ 服务器将响应返回客户端,同第①个,这些响应也可以是显式的数据或隐式的数据

Servlet工作原理

(1)Servlet接口定义了Servlet与servlet容器之间的契约。这个契约是Servlet容器将Servlet类载入内存并产生Servlet实例和调用它具体的方法。在一个应用程序中每种Servlet类型只能有一个实例。

(2)用户请求使Servlet容器调用Servlet的Service()方法并传入一个ServletRequest对象和一个ServletResponse对象。这些对象都是由Servlet容器例如TomCat封装好的并不需要程序员去实现程序员可以直接使用。

  • ServletRequest中封装了当前的Http请求ServletResponse表示当前用户的Http响应

(3)对于每一个应用程序Servlet容器还会创建一个ServletContext对象。这个对象中封装了上下文应用程序的环境详情。每个应用程序只有一个ServletContext。每个Servlet容器也都有一个封装Servlet配置的ServletConfig对象。

Servlet的使用

Java Servlet 是运行在带有支持 Java Servlet 规范的解释器的 web 服务器上的 Java 类。Servlet 可以使用 javax.servletjavax.servlet.http 包创建,它是 Java 企业版的标准组成部分。它们之间的关系如下图所示:

使用

创建一个类实现Servlet接口,重写其中的方法

public class LoginServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //初始化方法
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public void service(ServletRequest res, ServletResponse resp) throws ServletException, IOException {
        //处理get/post请求的方法
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
        //销毁的方法
    }
}

继承HttpServlet类常用

public class LoginServlet implements Servlet {
    @Override
    public void doGet(HttpServletRequest res, HttpServletResponse resp) throws ServletException, IOException {
        //处理get请求的方法
    }
    @Override
    public void doPost(HttpServletRequest res, HttpServletResponse resp) throws ServletException, IOException {
        //处理get请求的方法
    }
   
}

部署配置

容器Tomcat在得到客户端的请求后但不知道去交给哪一个servlet去处理所以需要进行部署有两种方式

方式一web.xml文件部署Servlet的映射关系

<servlet>
    <servlet-name>自定义名称</servlet-name>
    <servlet-class>处理请求的类的完整路径</servlet-class>
</servlet>
<servlet-mapping><!-- mapping 表示映射 -->
    <servlet-name>自定义名称</servlet-name>
    <url-pattern>请求名</url-pattern>
</servlet-mapping>

这个xml标签的执行顺序

请求过来以后->web.xml->servlet-mapping标签中的url-pattern标签中的内容和请求名进行匹配->匹配成功后找对应的servlet-mapping标签中的servlet-name->去servlet标签中找和上一个servlet-name相同的name值->去找servlet标签中的servlet-class中处理类的完整路径。

方式二:@WebServlet注解

注解这个方式是Servlet3.0版本后才支持的,它里面可以添加如下属性

属性名 类型 描述
name String 指定Servlet 的 name 属性,默认为类的全限定名
value或者urlPatterns String 指定Servlet处理的url。等价于web.xml中的<url-pattern>标签。
asyncSupported boolean 指定Servlet是否支持异步操作模式
displayName String 指定servlet的显示名
initParams webInitParam[] 配置初始化参数
loadOnStartup int 指定servlet的加载顺序默认不配置或数值为负数时表示客户端第一次请求Servlet时再加载0或正数表示启动应用就加载正数情况下数值越小加载该Servlet的优先级越高

例如:

@WebServlet(value = "/login")
public class LoginServlet implements Servlet  {
	//code
}

Servlet的生命周期

当客户端首次发送第一次请求后,由容器(web服务器(tomcat))去解析请求根据请求找到对应的servlet判断该类的对象是否存在不存在则创建servlet实例调取init()方法进行初始化操作初始化完成后调取service()方法由service()判断客户端的请求方式如果是get则执行doGet()如果是post则执行doPost()。处理方法完成后,作出响应结果给客户端。单次请求处理完毕。

当用户发送第二次以后的请求时会判断对象是否存在但是不再执行init()而直接执行service方法调取doGet()/doPost()方法。

当服务器关闭时调取destroy()方法进行销毁。

Servlet接收/响应请求

客户端发送数据给服务器端的请求方式:

请求方式 请求类型 举例
通过form表单 get/post提交 < form action="请求" method="get/post">< /form>
通过a标签发送数据 get提交 < a href = "请求">< /a>
通过地址栏直接拼接 get请求 url/请求?key=value&key=value
js提交数据 get请求 location.href=“目标请求?key=value&key=value”

get/post请求的比较

  1. 地址栏呈现

    • GET请求请求的数据会附加在URL之后?分割URL和传输数据多个参数用&连接。
    • POST请求POST请求会把请求的数据放置在HTTP请求包的包体中。

    因此GET请求的数据会暴露在地址栏中而POST请求则不会。

  2. 传输数据的大小

    • 在HTTP规范中没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中对于GET特定的浏览器和服务器对URL的长度有限制。因此在使用GET请求时传输数据会受到URL长度的限制。
    • 对于POST由于不是URL传值理论上是不会受限制的但是实际上各个服务器会规定对POST提交数据大小进行限制Apache、IIS都有各自的配置。
  3. 安全性

    POST的安全性比GET的高。比如在进行登录操作通过GET请求用户名和密码都会暴露再URL上因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因此时的用户名和密码就很容易被他人拿到。除此之外GET请求提交的数据还可能会造成Cross-site request frogery攻击

HttpServletRequest和HttpServletResponse对象中分别封装了当前的Http请求和响应它们中都有一些方法来处理请求和响应。

HttpServletRequest类常用方法

修饰 方法名 描述
String getParameter(String name) 根据表单组件名称获取提交数据返回值是String服务器在接收数据时使用字符串统一接收
String[] getParameterValues(String name) 获取表单组件对应多个值时的请求数据
void setCharacterEncoding(String charset) 指定每个请求的编码(针对post请求才起作用)
RequestDispatcher getRequestDispatcher(String path) 转发,返回一个RequestDispatcher对象该对象的forward( )方法用于转发请求
Session getSession() 取得当前会话的Session对象
void setAttribute(“key”,value) 存值
void getAttribute(“key”) 取值,需要向下转型

HttpServletResponse类常用方法

修饰 方法名 描述
void addCookie(Cookie var1) 给这个响应添加一个cookie
void sendRedirect(String var1) 重定向,发送一条响应码,将浏览器跳转到指定的位置
PrintWriter getWriter() 获得字符流通过字符流的write(String s)方法可以将字符串设置到response 缓冲区中随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端可以返回html/js代码等
void setContentType() 设置响应内容的类型

重定向与转发的区别

转发:httpServletRequest.getRequestDispatcher("目标地址").forward(传递参数)

重定向:httpServletResponse.sendRedirect("目标地址")

相同点:都用来跳转页面

不同点:

  • 重定向时地址栏会改变request中存储的数据会丢失。转发时地址栏显示的是请求页面的地址request数据可以保存。

  • 转发属于一次请求一次响应,重定向属于两次请求(地址栏修改了两次)两次响应。

会话Session和Cookie

会话的概念:从打开浏览器到关闭浏览器,期间访问服务器就称为一次会话

会话跟踪是Web程序中常用的技术用来跟踪用户的整个会话。保持对用户会话期间的数据管理。常用的会话跟踪技术是Cookie与Session。

  • Cookie通过在客户端记录信息确定用户身份
  • Session通过在服务器端记录信息确定用户身份。

Session

session会话的数据可以在多个页面中共享,即使重定向页面,数据不会丢失

Session常用方法

修饰 方法名 描述
void setAttribute(String key,Object value) 以key/value的形式保存对象值,将数据存储在服务器端
Object getAttribute(String key) 通过key获取对象值
Enumeration getAttributeNames() 返回Session中存在的属性名(key)
long getLastAccessedTime() 返回Session的最后活跃时间。
long getCreationTime() 返回Session的创建日期。返回类型为long常被转化为Date类型例如Date createTime = new Date(session.get CreationTime())
void invalidate() 设置session对象失效
String getId() 获取sessionid,当第一次登录成功后session会产生一个唯一的id浏览器之后访时如果发现id值还是之前id那么说明 当前访问的属于同一个会话
void setMaxInactiveInterval(int interval) 设定session的有效时间单位为s秒默认的有效时间:30分钟
int getMaxInactiveInterval() 获取session的有效时间(以秒为单位)
boolean isNew() 返回该Session是否是新创建的
void removeAttribute(String key) 从session中删除指定名称(key)所对应的对象

Session的生命周期

Session保存在服务器端。为了获得更高的存取速度服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂当大量客户访问服务器时可能会导致内存溢出。因此Session里的信息应该尽量精简。

Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session也可以用request.getSession(true)强制生成Session。

Session生成后只要用户继续访问服务器就会更新Session的最后访问时间并维护该Session。用户每访问服务器一次无论是否读写Session服务器都认为该用户的Session“活跃active”了一次。

由于会有越来越多的用户访问服务器因此Session也会越来越多。为防止内存溢出服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器Session就自动失效了。

Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(long interval)修改。Session的超时时间也可以在web.xml中修改。另外通过调用Session的invalidate()方法可以使Session失效。

<session-config>
	<session-timeout>30</session-timeout>  //30分钟
</session-config>

Cookie是客户端(一般指浏览器)请求服务器后,服务器发给客户端的一个辨认标识,保存在客户端,当客户端再次向服务器发送请求时,会携带着这个辨认标识,服务器就可以通过这个标识来识别客户端的身份或状态等。

Cookie的设置和获取

通过HttpServletResponse.addCookie的方式设置Cookie

Cookie cookie = new Cookie("jieguo","true");
response.addCookie(cookie);

服务端获取客户端携带的cookie通过HttpServletRequest获取

Cookie[] cookies = request.getCookies();
if(cookies != null)
    for(Cookie c : cookies){
        String name = c.getName();//获取Cookie名称
        if("jieguo".equals(name)){
            String value = c.getValue();//获取Cookie的值
            bool = Boolean.valueOf(value);//将值转为Boolean类型	
        }
	}
}

删除Cookie

通过设置同名Cookie的最大存活时间为0删除Cookie是指使浏览器不再保存Cookie使Cookie立即失效

举例使name为username的Cookie立即失效

//1.创建一个name为username的Cookie
Cookie cookie = new Cookie("username", "aaa");
//2.设置Cookie的有效时间为0
cookie.setMaxAge(0);//删除cookie的关键
//3.将cookie发送给浏览器来替换同名Cookie
response.addCookie(cookie);

Cookie的有效时间

Cookie发送给浏览器以后浏览器并不会永久保存也就是到了一定的时间以后浏览器会自动销毁Cookie。 Cookie的默认有效时间为一次会话(一次打开关闭浏览器的过程)我们也可以手动指定Cookie的有效时间

//setMaxAge用来设置Cookie的最大有效时间需要int型的参数代表有效的秒数
cookie.setMaxAge(秒数)
    //当参数大于0时会设置为指定的秒数
    cookie.setMaxAge(30);
    //当参数等于0时,浏览器不会保存Cookie,Cookie立即失效
    cookie.setMaxAge(0);
    //当参数小于0时和不设置是一样当前会话有效
    cookie.setMaxAge(-100);
//设置一个永久有效的Cookie并非永久只是使Cookie的生命很长而已
cookie.setMaxAge(60*60*24*365*10);

Session和Cookie的区别

  • Cookie数据保存在客户端Session数据保存在服务器端。
  • Session是由应用服务器维持的一个服务器端的存储空间用户在连接服务器时会由服务器生成一个唯一的SessionID用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端用Cookie保存的用户提交页面时会将这一SessionID提交到服务器端来存取Session数据。这一过程是不用开发人员干预的。所以一旦客户端禁用Cookie那么Session也会失效。
  • Cookies是属于Session对象的一种。但有不同Cookies不会占服务器资源是存在客服端内存或者一个Cookie的文本文件中而Session则会占用服务器资源。所以尽量不要使用Session而使用Cookies。但是我们一般认为Cookie是不可靠的Cookies是保存在本机上的但是其信息的完全可见性且易于本地编辑性往往可以引起很多的安全问题。