Servlets & JSP

Servlets & JSP

java开发:

  • cs(client、server)
    客户端、服务器。必须安装客户端,服务端更新客户端必须更新才能应用。 如大型游戏、qq。
  • bs(browser、server)。 浏览器、服务器。通过浏览器就能访问,不需要安装客户端。

bs原理
浏览器–应用程序服务器–数据库服务器

bs结构程序完全部署在应用程序服务器中,基于请求和响应,基于http协议。一次请求对应一次响应。

tomcat服务器–小型开源免费的应用程序服务器,默认端口号8080。学习、开发中应用tomcat服务器,项目上线应用收费的应用程序服务器weblogic….

Tomcat目录:
  • bin 启动、关闭tomcat服务器应用的一些命令
  • conf 配置文件
  • lib jar包
  • webapps 部署到服务器中的应用程序
  • work Tomcat把由JSP生成的Servlet放于此目录下。

URL格式:
http://ip地址:tomcat的端口号/项目名/访问的路径

请求的方式:

  • get: 显示提交、不安全、、不能直接支持中文。
      表单的method属性设置为get时(默认)
      用户的输入信息会在地址栏显示
      输入url
      点击链接

  • post: 隐式提交、安全、支持中文。
      表单的method属性设置为post时

Servlet API

Servlet接口
    └─GenericServlet抽象类
        └─HttpServlet抽象类(基于http协议),我们所使用的servlet根基类。

ServletRequest、ServletResponse
    └─HttpServletRequest、HttpServletResponse。基于http协议的请求、响应

javax.servlet Interface Servlet
All Known Implementing Classes:
GenericServlet

Servlet

javax.servlet
Interface Servlet
All Known Implementing Classes: GenericServlet

ServletConfig

javax.servlet
Interface ServletConfig
All Known Implementing Classes:
GenericServlet

ServletContext

javax.servlet
Interface ServletContext

ServletRequest

javax.servlet
Interface ServletRequest
All Known Subinterfaces:
HttpServletRequest

ServletResponse

javax.servlet
Interface ServletResponse
All Known Subinterfaces:
HttpServletResponse

GenericServlet

javax.servlet
Class GenericServlet
java.lang.Object
 └─javax.servlet.GenericServlet
All Implemented Interfaces:
java.io.Serializable, Servlet, ServletConfig
Direct Known Subclasses:
HttpServlet

HttpServlet

javax.servlet.http
abstract Class HttpServlet
java.lang.Object
 └─javax.servlet.GenericServlet
  └─javax.servlet.http.HttpServlet
All Implemented Interfaces:
java.io.Serializable, Servlet, ServletConfig

HttpServletRequest

javax.servlet.http
Interface HttpServletRequest
All Superinterfaces:
ServletRequest

HttpServletResponse

javax.servlet.http
Interface HttpServletResponse
All Superinterfaces:
ServletResponse

RequestDispatcher

javax.servlet
Interface RequestDispatcher

自定义Servlet类的创建

  1. 继承自HttpServlet类。
  2. 重写doGet()方法、doPost()方法。
  3. Web.xml文件中配置Servlet类(或servlet注解)。

路径问题:

tomcat默认端口号:8080,修改tomcat的端口号:

<!--tomcat--conf文件夹--server.xml中修改端口号-->
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

项目调试:

  • 如果修改了web.xml 必须重新启动服务器
  • 修改了java代码,需要重新部署
  • 修改了页面代码,不需要重新部署

web.xml: 最先被加载的配置文件

  • 配置servlet(配置访问路径)
  • 配置欢迎页面,一般用于设置主页

容器如何处理请求:

  1. 用户点击一个链接,其URL指向一个servlet而不是静态页面。
  2. 容器“看出来”这个请求要的是一个servlet,所以容器创建两个对象:HTTPServletRequestHttpServletResponse
  3. 容器根据请求中的URL找到正确的servlet,为这个请求创建或分配一个线程,并把请求和相应对象传递给这个servlet线程。
  4. 容器调用servlet的service()方法。根据请求的不同类型,service()方法会调用doGet()或doPost()方法。
  5. doGet()或doPost()方法生成动态页面,并把这个页面“填入”响应对象。要记住,容器还有相应对象的一个引用。
  6. 线程结束,容器把响应对象转换为一个Http响应,把它发送给客户,然后删除请求和相应对象。

servlet的生命周期:

HTTP请求 → 解析请求 → 创建servlet实例 → 调用init()方法 → 调用service()方法 → 输出响应信息 → 响应 → 调用destroy()方法。

  • 实例化阶段:Servlet容器调用构造函数。
  • 初始化阶段:容器调用init()方法。
  • 请求处理阶段:如果请求Servlet,则容器调用service()方法(service()方法根据请求的方式调用doGet()或doPost()方法)。
  • 销毁阶段:销毁实例之前调用destroy()方法。

servlet采用多线程单实例的模式:

  • 第一次访问servlet:实例化阶段–初始化阶段–请求处理阶段
  • 第二次及以上访问servlet:请求处理阶段。

servlet中不应该自定义成员变量。

Servlet接口

定义了所有Servlet要实现的方法。

Servlet常用方法:

方法名称功能描述
public void init(ServletConfig config)由servlet容器调用,用于完成Servlet对象在处理客户请求前的初始化工作
public void service(ServletRequest req, ServletResponse)由servlet容器调用,用来处理客户端的请求
public void destroy()由servlet容器调用,释放Servlet对象所使用的资源
public ServletConfig getServletConfig()返回ServletConfig对象,该对象包含此servlet的初始化和启动参数。返回的ServletConfig对象是传递给init()方法的对象
public String getServletInfo()返回有关servlet的信息,比如作者、版本和版权。返回的字符串是纯文本。
ServletConfig接口

在Servlet初始化过程中获取配置信息,一个Servlet只有一个ServletConfig对象。

ServletConfig常用方法:

方法名称功能描述
public String getInitParameter(String name)获取web.xml中设置的以name命名的初始化参数值
public ServletContext getServletContext()返回Servlet的上下文对象引用
GenericServlet抽象类

提供了Servlet与ServletConfig接口的默认实现方法。

Servlet接口的常用方法:

方法名称功能描述
public void init(ServletConfig config)调用Servlet接口中的init()方法。此方法还有一无参的重载方法,其功能与此方法相同
public String getInitParameter(Stringname)返回名称为name的初始化参数的值
public ServletContext getServletContext()返回ServletContext对象的引用
HttpServlet抽象类

继承于GenericServlet,处理HTTP协议的请求和响应。

HttpServlet的常用方法:

方法名称功能描述
public void service(ServletRequest req, ServletResponse res)调用GenericServlet类中service()方法的实现
public void service(HttpServletRequest req, HttpServletResponse res)接收HTTP请求,并将它们分发给此类中定义的doXXX()方法
public void doXXX(HttpServletRequest req, HttpServletResponse res)根据请求方式的不同,分别调用相应的处理方法,例如doGet()、doPost()等
ServletRequest接口

获取客户端的请求数据。

ServletRequest接口常用方法:

方法名称功能描述
public Object getAttribute(String name)获取名称为name的属性值
public void setAttribute(String name, Object object)在请求中保存名称为name的属性
public void removeAttribute(String name)清除请求中名字为name的属性
HttpServletRequest接口

除了继承ServletRequest接口中的方法,还增加了一些用于读取请求信息的方法。

HttpServletRequest的常用方法:

方法名称功能描述
public String getContextPath()返回请求URI中表示请求上下文的路径,上下文路径是请求URI的开始部分
public Cookie[] getCookies()返回客户端在此次请求中发送的所有cookie对象
public HttpSession getSession()返回和此次请求相关联的session,如果没有给客户端分配session,则创建一个新的session
public String getMethod()返回此次请求所使用的HTTP方法的名字,如GET、POST
RervletResopnse接口

向客户端发送响应数据。

RervletResopnse接口的常用方法:

方法名称功能描述
public PrintWriter getWriter()public PrintWriter getWriter()
public String getCharacterEncoding()返回在响应中发送的正文所使用的字符编码
public void setCharacterEncoding()设置发送到客户端的响应的字符编码
public void setContentType(String type)设置发送到客户端的响应的内容类型,此时响应的状态属于尚未提交
HttpServletResponse接口

除了继承ServletResopnse接口中的方法,还增加了新的方法。

HttpServletResopnse的常用方法:

方法名称功能描述
public void addCookie(Cookie cookie)增加一个cookie到响应中,这个方法可多次调用,设置多个cookie
public void addHeader(String name,String value)将一个名称为name,值为value的响应报头添加到响应中
public void sendRedirect(String location)发送一个临时的重定向响应到客户端,以便客户端访问新的URL
public void encodeURL(String url)使用session ID对用于重定向的URL进行编码
ServletContent接口

获取Servlet上下文。

ServletContext常用方法:

方法名称功能描述
public String getInitParameter(String name)获取名称为name的系统范围内的初始化参数值,系统范围内的初始化参数可以在部署描述符中使用context-param元素定义
public void setAttribute(String name, Object object)设置名称为name的属性
public Object getAttribute(String name)获取名称为name的属性
public String getRealPath(String path)返回参数所代表目录的真实路径
public void log(String message)记录一般日志信息

字符编码:

  GBK2312、GBK、BIG5、ISO8859-1(默认采用此字符集)、UTF-8、

能读取文本框内中文内容不乱码:

request.setCharacterEnding("utf-8");

输出中文内容不乱码:

resopnse.setContentType("text/html; charset=utf-8");

每种文件都有各自的内容类型(mine-type),在servers>web.xml文件中有定义,html对应–text/html。

初始化参数:

  • servlet类初始化参数:在web.xml中的servlet节点中配置,有效范围是当前servlet类。
  • servlet上下文对象的初始化参数(ServletContext):在web.xml中配置,有效范围是当前项目中所有servlet类。
<!--Servlet初始化参数配置-->
<web-app>
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>org.jbit.servlet.HelloServlet</servlet-class>
        <init-param>
            <param-name>initParam</param-name>
            <param-value>Hello Servlet</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/HelloServlet</url-pattern>
    </servlet-mapping>
</web-app>
<!--获取Servlet初始化参数-->
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("处理请求时,doGet()方法被调用。");
    String initParam = getInitParameter("initParam");
    System.out.println(initParam);
}
<!--配置Servlet上下文-->
<web-app>
    <context-param>
        <param-name>contextParam</param-name>
        <param-value>Hello Servlet</param-value>
    </context-param>
    <!--省略其他配置-->
</web-app>
<!--读取Servlet上下文-->
public class HelloServlet extends HttpServlet {
    // …省略其他代码
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("处理请求时,doGet()方法被调用。");
        String initParam = getInitParameter("initParam");
        String contextParam = this.getServletContext().getInitParameter("contextParam");
        System.out.println("Servlet初始化参数" + initParam);
        System.out.println("系统初始化参数" + contextParam);
    }
}

servlet类打印html代码输出:

resopnse.setContentType("text/html; charset=utf-8");
PrinterWriter out = request.getWriter();
out.println("<h1>HELLO WORLD</h1>");

页面跳转的两种方式:

  • 请求转发:
    1. 转发是在服务器端发挥作用,通过forward()将提交信息在多个页面间进行传递。
    2. 客户端浏览器的地址栏不会显示出转向后的地址。
  • 重定向:
    1. 重定向是在客户端发挥作用,通过请求新的地址实现页面转向,不能携带数据。
    2. 在地址栏中可以显示转向后的地址。
//重定向
response.sendRedirect("URL");

//请求转发
RequestDispather dispather = request.getResquestDispather("URL");
dispather.forword(request, reponse);

  web服务器保存在客户端的一系列文本信息。

//创建Cookie对象
Cookie cookie = new Coolie(String key, String value);
//写入Cookie
response.addCookie();
//读取Cookie
Coolies[] cookies = request.getCookies();

Cookie对象的常用方法:void setMaxAge(int second)、 void setValue(String key)、 String getName()、 String getValue()、 String getMaxAge()。

使用部署文件将URL映射到sevlet

将servlet部署到Web容器时,会创建一个相当简单的XML文档,这称为部署描述文件(DD),部署描述文件会告诉容器如何运行你的servlet和JSP。

部署描述文件(DD)提供了一种“声明”机制来定制Web应用,而无需修改源代码!

DD的优点:

  • 尽量少改动已经测试通过的源代码。
  • 即使你手上并没有源代码,也可以对应用功能进行调整。
  • 不用重新编译和测试任何代码,也可以让你的应用适应不同的资源(如数据可)。
  • 可以更容易地维护安全信息,如访问控制列表和安全角色。
  • 非程序员也可以以修改和部署Web应用,而你可以留出精力,做出有意思的事情,比如看看你的行装是否适合夏威夷之旅。

servlet的存在就是要为客户服务。servlet的任务时得到一个客户的请求,在发出一个响应。

service()方法总是在自己的栈中调用。容器运行多个线程来处理对一个servlet的多个请求。

谁来实现HttpServletRequest和HttpServletResponse接口?这些类在API中吗?——容器不在。他们要由开发商来实现。

HttpSession

javax.servlet.http.HttpSession接口表示一个会话,我们可以把一个会话内需要共享的数据保存到HttpSession对象中!

通常把HttpSession直接称为Session。

获取Session对象:

HttpSession session = request.getSession();

常用方法:void setAttribute(String key, Object value)、 Object getAttribute(String key)、 void invalidate()、 String getId()、 void setMaxInactiveInterval()、 int getMaxInactiveInterval()、 void removeAttribute()。

注意:存值时,key相同value会覆盖。session失效,其中的值会消失。

session的生命周期:打开浏览器session有效,关闭浏览器/调用invalidata()方法/超时session失效(销毁),默认有效时间为20分钟。

手动设置session失效:

//使用session的方法
session.setMaxInactiveInterval(int second);

//配置文件,就近有效原则,项目下的web.xml优先级高于Tomcat中的web.xml。
<seesion-config>
    <session-timeout>int minutes</session-timeout>
</session-config>

session与窗口的关系:

  • 每个session对象都与浏览器一一对应,重新开启一个浏览器,相当于重新创建一个session对象(版本不同可能会有差异)。
  • 通过超链接打开的新窗口,新窗口的session与其父窗口的session相同。

session的应用场合:
- 登录成功后存储用户对象。
- 安全退出。
- 后台页面的访问控制。

Servlet下载
package gacl.response.study;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 文件下载
 */
public class ResponseDemo02 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        downloadChineseFileByOutputStream(response);//下载中文文件
    }

    /**
     * 下载中文文件,中文文件下载时,文件名要经过URL编码,否则会出现文件名乱码
     * @param response
     * @throws FileNotFoundException
     * @throws IOException
     */
    private void downloadChineseFileByOutputStream(HttpServletResponse response)
            throws FileNotFoundException, IOException {
        String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径
        String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名
        //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
        response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
        InputStream in = new FileInputStream(realPath);//获取文件输入流
        int len = 0;
        byte[] buffer = new byte[1024];
        OutputStream out = response.getOutputStream();
        while ((len = in.read(buffer)) > 0) {
            out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器
        }
        in.close();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

JSP

JSP内置对象

JSP内置对象是由web容器创造出来的一组对象。常用的JSP内置对象有:out、 request、 response、 session、 application。

  • out 对象:用于向客户端输出信息。
  • request对象:主要用于处理客服端的请求。
  • response对象:用于响应客户请求并向客户端输出信息。
  • session对象:用于记录会话状态的相关信息。
  • application对象:实现用户之间的数据共享。

指令元素:(3个)
<%@指令元素名 属性名=”属性值” 属性名2=”属性值2”… %>

page指令
通过page指令的属性设置页面的属性信息
import 导包
contentType 内容类型、字符集
每个jsp页面第一行必须是page指令

脚本元素:三个(java代码)
小脚本<% %> java代码
表达式<%= %> 输出
声明<%! %> 方法 (不常用)

注释:
html注释 响应给用户时查看源文件可以看到
jsp注释 响应后查看源文件不可以看到
小脚本中应用java注释

jsp处理流程(执行过程)
翻译阶段 .jsp—.java (Servlet类)
编译阶段 .java—.class
运行阶段 将显示内容显示给用户

为什么第一次访问jsp页面慢,页面内容不改时再次访问速度变快?
第一次访问jsp页面时需要经历翻译-编译-运行阶段
页面内容不改时再访问 可以重用.class文件 直接运行(只经历运行阶段)

jsp与servlet的关系
实质是一个技术
jsp首先会翻译成一个Servlet类再编译、运行
jsp、servlet都能实现页面显示、处理代码
jsp显示更好
servlet处理更好
jsp和servlet搭配应用

tomcat服务器 work文件夹–jsp所翻译的.java、编译的.class文件

jsp页面报错的代码行数–.java文件行数

调错:
404 路径、run as on Server
500 语法错误,抛异常,查看异常信息,提示错误行数
应用system.out…输出
浏览器中右键查看源文件(jsp)

jsp指令元素
page
include 引入页面、包含页面
<%@include file=”页面路径”%>

jsp的作用范围
page 仅在当前页面有效
pageContext对象
request 在当前请求中有效的
点击链接、输入url、表单提交、刷新页面 请求有效(诞生)
页面跳转(路径变化了) 刷新页面 请求失效了 会产生新的请求
如果在request作用范围中存值,必须采用请求转发跳转,跳转后页面中可以获取到request中的值。
session 当前会话中有效
打开浏览器session有效
关闭浏览器、session超时、session手动卸载(session.invalidate())session失效
application 当前应用程序中有效
打开服务器时application有效
关闭服务器时application失效

作用范围从小到大
page–request–session–application
ServletContext

应用:
page 用的很少
request 一般用来存用一次的数据
session 一般用来存用户信息、购物车(跟踪)
application 范围最大的 一般用来存公有信息、计算访问人数

原则:
能用小的就不用大的

请求转发和重定向
如果在request作用范围中存值,必须采用请求转发跳转。
其他情况重定向

cookie和session的对比:

  • session:在服务器端保存用户信息,session中保存的是Object类型,随会话结束而将其存储的数据销毁,保存重要信息。
  • 在客户端保存用户信息,cookie中保存的是字符串,cookie可以长期保存在客户端,用来保存不重要信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值