Servlet和JSP

作者: WhyDoWeLive | 来源:发表于2019-08-16 15:44 被阅读0次

Servlet

Servlet/JSP应用架构

servlet无法独立运行,必须运行在Servlet容器中。Servlet容器将用户的请求传递给Servlet应用,并将结果返回给用户。Tomcat和Jetty就是当前最流行的Servlet/JSP容器。


Servlet/JSP应用架构.png
Servlet是一个Java程序
@WebServlet(name = "WxsFirstServlet", urlPatterns = {"/myServlet"})
public class MyServlet implements Servlet {
    private transient ServletConfig servletConfig;

    //保存配置信息,如@WebServlet注解中的属性,仅调用一次
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig = servletConfig;
    }

    //获得上述配置信息对象
    @Override
    public ServletConfig getServletConfig() {
        return servletConfig;
    }

    //容器会自动调用该方法处理请求,返回响应。
    //容器接到请求后,会自动创建ServletRequest和ServletResponse对象并传给service方法
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        String servletName = servletConfig.getServletName();
        servletResponse.setContentType("text/html");

        System.out.println(servletRequest.getParameter("id"));

        PrintWriter writer = servletResponse.getWriter();
        writer.print("<html><head></head><body>Hello from" + servletName + "</body></html>");
    }

    @Override
    public String getServletInfo() {
        return "MyServlet";
    }

    @Override
    public void destroy() {

    }
}

运行该程序,只需启动Tomcat并部署后,访问http://localhost:8080/项目名/MyServlet即可,此时,浏览器上将会显示我们返回的HTML页面

GenericServlet

上述实现Servlet的缺点是,有些方法没必要修改,但我们仍要重载。
GenericServlet实现了Servlet和ServletConfig接口,通过继承GenericServlet,只需实现Service方法即可实现Servlet

HttpServlet

主角!最常用!
HttpServlet有两个特性是GenericServlet所不具备的:

  • 不用覆盖Service方法,而是覆盖doGet、doPost、doHead等方法。HttpServlet中的Service方法会根据HTTP请求的Method调用响应的doXXX方法
  • 使用HttpServletRequest和HttpServletResponse,而不是ServletRequest和ServletResponse
处理HTML表单

当用户提交(submit)表单时,在表单元素中输入的值就会被当作请求参数发送到服务器。

HttpServlet&HTML表单示例

一开始HTML页面竟然是这么返回的。。。>_<
该Servlet有两个方法

  • 方法1,返回HTML,包含Form表单,用于填写信息。提交表单后,会调用第二个方法
  • 方法2,返回HTML,显示上面表单所填写的信息
@WebServlet(name="FormServlet", urlPatterns={"/form"})
public class FormServlet extends HttpServlet
{
    //这里是要返回给客户端一个包含Form表格的HTML,用于填写信息
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExeption
    {
        response.setContentType("text/html");
        Printwriter writer = response.getWriter();
        writer.print("<html>");
        ...
        //<form>的action属性为默认,表示该表单会被提交给请求它时用的相同的URL,以便提交表格后调用下一个方法
        writer.println("<form method='post'>")
        //<table><tr><td><input>等组件
        writer.print("</html>");
    }

    //这里是要返回一个HTML,展示用户在上一个方法返回的HTML页面中填写的表格信息
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("<html>");
        //<table><tr><td><input>等组件
        ...
        writer.println("</html>");
    }
}
部署描述符

前面的例子都是利用@WebServlet配置Servlet应用程序,例如用一个路径映射到一个Servlet。本节介绍另一种方法,即部署描述符。部署描述符总是放在WEB-INF目录下,并且总是命名为web.xml

可将第一个例子中的@WebServlet去掉,编辑web.xml如下,可达到同样效果

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
           version="3.1">
    <servlet>
        <servlet-name>WxsFirstServlet</servlet-name>
        <servlet-class>MyServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>WxsFirstServlet</servlet-name>
        <url-pattern>/myServle3t</url-pattern>
    </servlet-mapping>

</web-app>

会话管理

HTTP是无状态的,默认下,Web服务器无法区分一个HTTP请求是否为第一次访问。
例如,一个Web邮件应用要求用户登陆才能查看邮件,因此,当用户输入用户名、密码登陆后,应用应能记住这些用户已经登陆,不应再次提示登陆。
本节将阐述4种不同的状态保持技术:URL重写、隐藏域、cookies和HTTPSession

URL重写

将必要的信息都记录在url中
仅适合与信息仅在少量页面间传递,形式如下
url?key-1=value-1&key-2=value-2&...&key-n=value-n

隐藏域

将必要的信息都记录在表单的隐藏域,表单提交时,隐藏域的值也同时提交到服务器端。
隐藏域技术仅当网页有表单时有效。相对于URL重写的优势在于没有字符数限制,但也不适合跨越多个界面形式如下
<form ...>
<input type='hidden' name='id' value='1' 其它我们要保存的值>
</form>

Cookies
  • 构造cookie:Cookie cookie = new Cookie(name, value);
  • 将cookie发送到浏览器:httpServletResponse.addCookie(cookie);
  • 服务端获取浏览器提交的cookie:HttpServletRequest接口的getCookies()返回Cookie数组。若要查询某个特定名称cookie,需要遍历cookie数组。

浏览器在访问同一Web服务器时,会将之前收到的cookie一并发送。我试过,浏览器中的cookie默认会保存很久,即使关闭浏览器也不会消除cookie。可控制cookies的有效时间,例如将maxAge设置为0实现消除cookie。
cookies的问题在于用户可以通过改变其浏览器设置来拒绝接受cookies

HttpSession

一个用户有且仅有一个HttpSesison对象
HttpSession对象在用户第一次访问网站的时候自动被创建

常用接口
  • getSession:获得当前Session对象
  • setAttribute:将键值(可以是Serializable的接口)放入HttpSession。
  • getAttribute:取值
  • getAttributeNames:返回所有保存在Session中的值
  • 还有一些设置Session过期的接口,若果Session没过期且容器和应用没有关闭,则一直存放在服务端内存中

注意,所有保存在Session中的值都存储在内存中,并且不会被发送到客户端。Servlet容器为每个HttpSession生成唯一标识发送给浏览器(开发人员无需介入),在后续的请求中,浏览器会将标识提交给服务端,这样服务器可以识别该请求是由哪个用户发起的

JavaServer Pages(JSP)

Servlet的缺点
  • 生成响应报文的方式十分烦琐,writer.println("<tr> <td cospan='4' style......")
  • 文本和HTML标记硬编码,即使表现层需要改变背景颜色,也需要重新编译

Servlet解决上述的问题,现代JavaWeb应用会同时使用JSP和Servlet

JSP概述

JSP页面本质上是一个Servlet,但更便于开发。JSP是Servlet的补充,并不是取代Servlet技术,倾向于表现层的Servlet可用Servlet来代替
JSP页面在JSP容器中运行,一个Servlet容器通常也是JSP容器,如Tomcat就是一个Servlet/JSP容器

当一个JSP页面第一次被请求时,Servlet/JSP容器主要做以下两件事情:

  • 将JSP页面转化为对应的实现了javax.servlet.Servlet子接口实现类,使得每一个页面都是一个Servlet(在Tomcat目录下找到转换后的Servlet后,会发现响应HTML仍然是通过out.write(....)的方式写的)
  • 如果转换成功,容器编译、装载、实例化该Servlet类,像正常Servlet一样执行生命周期操作

JSP页面不同于Servlet的一个方面是,前者不需要添加注解或在部署描述符中配置映射URL,在应用程序目录中的每一个JSP页面可以直接在浏览器中输入路径页面访问。如:http://localhost:8080/ProjectName/welcome.jsp。添加新的JSP界面后,无须重启Tomcat

JSP页面可以包含模版数据和语法元素

  • 语法元素:具有特殊意义的JSP转换符,如<%,%>分别代表Java代码的起止符号,<%%>块又被称作scriplet。
  • 模版数据:除去语法元素外的一切是模板数据。模板数据会原样发送给浏览器,如HTML标记和文字
隐式对象

Servlet中,通过service方法能够拿到:HttpServletRequest、HttpServletResponse;通过init能够访问ServletConfig;通过HttpServletRequest的getSession访问HttpSession

在JSP中,可以通过使用如下隐式对象来访问上述对象:
request、response、config、session
另外还有

  • application,类型为ServletContext
  • out,类型为JspWriter
  • page,类型为HttpjspPage
  • pageContext,类型为HttpJspPage
  • exception,类型为Throwable

示例,在JSP中实现从HttpServletRequest对象中获取username的值

<%String userName = request.getparameter("username"); %>
指令

指令是JSP语法元素的第一种类型,用于指示JSP转换器如何翻译JSP页面为Servlet。只有page和include最重要

  • page:可以导入包、设置out缓冲区大小、是否使用session等
  • include:将另一个JSP或静态HTML文件嵌入到当前JSP中
表达式

<%= xxx%>等价于<% out.print(xxx)%>

声明

<%! xxx%>可用与声明或重写函数,声明和重写的函数可以在JSP页面中使用

禁用脚本元素

推荐的实践是:在JSP页面中用EL访问服务器端对象且不写Java代码。因此,需要通过在部署描述符中的<jsp-property-group>定义scripting-invalid元素,来禁用脚本元素

动作

useBean

<jsp:useBean id="today" class="java.util.Date">
<%=today%>

该代码创建一个Java.util.Date实例,并赋值给名为today的脚本变量,然后在表达式中使用

setProperty和getProperty

<jsp:useBean id="today" class="java.util.Date">
<jsp:setProperty name="today" property="time" value="12:00">
<jsp:getProperty name="today" property="time">

forward
将当前页面转向其它资源

<jsp:forward page="jspf/login.jsp">
    <jsp:param name="text" value="please login">
</jsp:forward>
错误处理

当应用遇到未捕获的异常时,用户将看到一个精心设计的网页解释放生了什么。
errorHandler.jsp使用Page指令的isErrorPage属性,表示自己是个错误页面

<%page isErrorPage="true"%>

bug.jsp故意抛出异常, 并且使用errorPage指向错误处理的页面

<%@page errorPage="erroHandler.jsp"%>

表达式语言

EL的目的是设计成可以轻松地编写免脚本的JSP页面。也就是说,页面不实用任何JSP声明、表达式或者scriptlet

EL表达式
${expression},返回结果为String
${a+b}${c+d},如果a+b=8,c+d=10,则结果为810
${object["property"]}或${object.property}可访问object的属性

在JSP页面中,可以利用JSP脚本来访问JSP隐式对象。但是,在免脚本的JSP页面中,则不可能访问这些隐式对象。EL允许通过提供一组它自己的隐式对象来访问不同的对象。不详细说了

JSTL

JSTL标准标签库是一个定制标签库的集合,用来解决像遍历Map或集合、条件测试、XML处理,甚至数据库访问和数据操作等常见的问题
在JSP页面使用JSTL库,必须通过类似以下格式使用taglib指令:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<c:out value="${x}"/>          <!-- 输出X的值 -->

相关文章

  • java EE 相关概念的总结

    1.JSP和Servlet Servlet和JSP是统一的,广义上的Servlet包含JSP和Servlet,真正...

  • Head First Servlet & JSP读书笔记

    Head First Servlet & JSP读书笔记 本书内容:Servlet和JSP Servlet和JSP...

  • jsp与servlet的区别与联系

    jsp和servlet的区别和联系: 1.jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,...

  • Java面试问题

    1、JSP: jsp和servlet的区别 jsp本质就是Servlet,jsp的工作原理是:JSP页面在执行的时...

  • 复习

    JSP: 1、jsp和servlet的区别 jsp本质就是Servlet,jsp的工作原理是:JSP页面在执行的时...

  • java 面试

    一、javaWeb知识点: jsp和servlet的区别 jsp本质就是Servlet,jsp的工作原理是:JSP...

  • Java面试题系列(七)——Java Web

    1. JSP和Servlet区别   JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JS...

  • Java Web部分(重要)

    1.jsp和 servlet 有什么区别? 答: jsp经编译后就成了Servlet(Jsp的本质就是Servl...

  • Java面试题(JavaWeb)

    64. jsp 和 servlet 有什么区别? jsp经编译后就变成了Servlet.(JSP的本质就是Serv...

  • 6.Java Web

    1.jsp 和 servlet 有什么区别? jsp经编译后就变成了Servlet.(JSP的本质就是Servle...

网友评论

    本文标题:Servlet和JSP

    本文链接:https://www.haomeiwen.com/subject/ctrfsctx.html