博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java之JSP和Servlet基础知识
阅读量:5740 次
发布时间:2019-06-18

本文共 11949 字,大约阅读时间需要 39 分钟。

JSP基础

JSP起源

JSP,Server Pager的简称。由SUN倡导并联合其它公司创建。

JSP是一门脚本语言

JSP可以嵌入到HTML中

JSP拥有Java语言的所有特性

面向对象、健壮、多线程、安全、可移植、高性能

JSP运行于JSP容器中

Tomcat、Jetty等。

JSP会被转换成Servlet

JSP->Servlet->Class文件。

Mac下常用shell命令:

pwd 打印当前目录 

ls 列出当前目录下的所有文件目录 
cd 更改目录 
.代表当前工作目录 
..代表上一级目录 
~代表用户根目录 
chmod更改权限

JSP基本语法

<% %> JSP代码段,可以输入任意的语言片段。 

<%! %> JSP声明,在JSP页面范围声明变量、函数和类。 
<%= %> JSP表达式 
JSP中HTML注释:

 
  • 1
  • 2
  • 1
  • 2

<%-- --%> JSP注释,不会被客户端浏览器看到。

JSP编译指令

通知Servlet引擎处理消息,它只在JSP程序被转化成Servlet的过程中起作用。

Page指令

在JSP最上方,用于指定语言,MIME,编码,错误跳转页面等等。 

技术支持  

1. contentType指定MIME和网页编码,无859. 

2. import导入多个java类,也可以使用多个page导入多个java类。 
3. errorPage表示JSP页面发生运行时错误跳转的页面。

<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.ArrayList,java.util.LinkedList" errorPage="err.jsp"%>
  • 1
  • 2
  • 1
  • 2

include指令

静态包含指令,可将外部文件包含进来。包含JSP文件时,不能有重复的变量声明。 

被导入的JSP编译指令会起作用。

<%@ include file="header.jsp"%>
  • 1
  • 1

taglib指令

JSP动作指令

客户端请求时动态执行的指令

forward指令

重定向指令,它下面的代码不会被执行,不会被返回到客户端。 

可以通过jsp:param指令向跳转的JSP页面传递参数。在目标JSP页面中通过request.getParameter()方法接收参数。

 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

include指令

动态包含指令,包含静态HTML和动态JSP文件。 

被导入的JSP编译指令不会起作用,并可以额外加参数。

  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在被包含的JSP文件中通过request对象将body背景色修改为传过去的值。

<%=request.getParameter("bgcolor")%>
  • 1
  • 1

useBean指令

JavaBean:一个公开的构造函数、属性有get、set方法、可序列化。 

例如:我们在接收提交的页面的,使用User这个bean,然后使用useBean指令配合setProperty、getProperty指令来接收显示提交内容: 
提交页面如下:

用户名:
密码:
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

接受页面如下:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

JSP内置对象

out对象

向客户端浏览器输出信息

<% out.println("out对象"); out.newLine(); out.println("
"); out.flush(); out.clearBuffer();//清空缓冲区的数据 //out.clear();//也是清空缓冲区数据,不同的是如果之前调用flush,则会抛出异常。 out.println("缓冲区大小:" + out.getBufferSize());//默认8K,可通过编译指令修改,如:<%@ page buffer="16kb" %> out.println("
"); out.println("当前缓冲区剩余大小:" + out.getRemaining()); %>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

request对象

request对象封装了客户端提交到服务器的请求信息,表单、cookie等信息。

请求的方法名:<%=request.getMethod() %>
//GET 请求的资源:<%=request.getRequestURI() %>
请求使用的协议:<%=request.getProtocol() %>
//HTTP/1.1 请求的服务器IP:<%=request.getServerName() %>
请求的服务器端口:<%=request.getServerPort() %>
客户端的IP地址:<%=request.getRemoteAddr() %>
客户端的主机名:<%=request.getRemoteHost() %>
getRequestURL:<%=request.getRequestURL() %>
getScheme:<%=request.getScheme() %>//Http //request.getParameter() 用于从客户端请求获取表单信息 request.setAttribute(); request.getAttribute(); 这两个方法用于在web组件间共享信息,比如JSP之间。 请求头信息; <% Enumeration
e = request.getHeaderNames(); while(e.hasMoreElements()){ String headerName = e.nextElement(); out.println(headerName+":"+request.getHeader(headerName)+"
"); } %>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

response对象

对客户端请求封装回复信息。

response.setHeader("Cache-Control", "no-cache");//浏览器读到这个头信息,就不会将网页信息存到缓存。还有public,private等 response.setIntHeader("Refresh", 2);//每隔2秒刷新一次 //response.sendRedirect("index.jsp");//重定向到另一个JSP网页 //设置Cookie Cookie cookie = new Cookie("ben","deng"); cookie.setMaxAge(3600);//单位为s response.addCookie(cookie);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

session对象

HTTP是无状态的。服务器使用session可以保存客户端浏览器的信息。

<%! SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); %> sessionId= <%=session.getId() %>
session创建时间= <%=sdf.format(new Date(session.getCreationTime())) %>
session最后访问时间= <%=sdf.format(new Date(session.getLastAccessedTime())) %>
session失效时间: <%= session.getMaxInactiveInterval()%>//默认1800s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

session失效时间可以通过修改部署描述符来实现。

 
10
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

如果不生效,需要删掉work目录的文件。

application对象

应用一启动就会生成application对象。web应用不关闭,application就一直存在。 

servlet的环境通过调用getServletConfig().getContext()方法获得。作用域是application(整个程序运行期)。它提供了关于服务器版本,应用级初始化参数和应用内资源绝对路径,注册信息的方式。

服务器信息:<%=application.getServerInfo() %> 应用信息:<%=application.getServletContextName() %> 主机信息:<%=application.getVirtualServerName() %>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

由于Application对象是随应用的生命周期存在,所以通过它可以对一些配置进行全局加载和存储。

config对象

代表当前JSP程序的配置信息。一般JSP在应用中作为View层使用,一般使用较少,在Servlet中用的比较多。读取的配置信息来自web.xml。

<%=config.getInitParameter("name") %>
  • 1
  • 1

在web.xml中配置一个servlet:

 
config
/jsp/config.jsp
name
name
pass
pass
config
/*
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在config.jsp中,使用

String name = config.getInitParameter("name"); String pass = config.getInitParameter("pass");
  • 1
  • 2
  • 1
  • 2

取出配置在web.xml中的信息。

exception对象

exception对象只有在page指令中具有属性isErrorPage="true"时才有效。它就是Java中普通的Throwable对象。 

通过JSP错误页面中一个catch块已经益出但没有捕获的java.lang.Throwable的任意实例,传向了errorPage的URI。 
比如在indx.jsp中运行如下代码

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" errorPage="exception.jsp"%> try{ int c = 3/0; }catch(Exception e){ }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在exception.jsp中:

<% out.print(exception.getLocalizedMessage()); %>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

页面输出/ by zero。

page对象

继承自Object对象,代表当前JSP页面。

pageContext对象。

pageContext对象提供所有四个作用域层次的属性查询和修改能力,它也提供了转发请求到其它资源和包含其他资源的方法。该对象的方法都是抽象方法。

JSP作用域

作用域规定的是变量的有效期限。JSP有四大作用域:Request、Page、Session、Application。 

我们使用public Object getAttribute(String name)获得变量值, 
使用public void setAttribute(String name, Object value)将变量值保存到对应作用域中。

对象 说明 类型 作用域
request 请求对象 javax.servlet.ServletRequest Request
response 响应对象 javax.servlet.SrvletResponse Page
pageContext 页面上下文对象 javax.servlet.jsp.PageContext Page
session 会话对象 javax.servlet.http.HttpSession Session
application 应用程序对象 javax.servlet.ServletContext Application
out 输出对象 javax.servlet.jsp.JspWriter Page
config 配置对象 javax.servlet.ServletConfig Page
page 页面对象 javax.lang.Object Page
exception 异常对象 javax.lang.Throwable page

如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。 

从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。 
   
如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。 
所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。

如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。 

所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。

如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。 

整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。

application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。 

与上述三个不同的是,application里的变量可以被所有用户共用。如果用户甲的操作修改了application中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page, request,session都是完全隔离的,无论如何修改都不会影响其他人的数据。

初识Servlet

Servlet = Server + Applet。它是一个特殊的Java类。 

下面新建一个Servlet:

public class Hello extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //super.doGet(req, resp); PrintWriter pw = resp.getWriter(); pw.println("Hello Servlet"); pw.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //super.doPost(req, resp); doGet(req,resp); } @Override public void init() throws ServletException { System.out.println("hello init()"); super.init(); } @Override public void destroy() { System.out.println("hello destroy()"); super.destroy(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在web.xml中进行配置:

 
hello
com.ben.servlet.Hello
hello
/hello
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

使用tomcat,进行运行。localhost:8080/hello,即可显示Hello Servlet。我是在IDEAIU中进行的,如果在Eclipse中路径可能有变化,需要加工程名。

如果浏览器出现HTTP Status 405 - HTTP method GET is not supported by this URL,注释掉doGet和doPost的父类调用即可。

Servlet处理流程

Servlet-Process 

客户端浏览器发出一个请求,tomcat内置web Server接收到请求,将请求转达给Servlet容器,Servlet容器会加载Servlet实例。Servlet使用HttpServletRequest接收请求实例,Servlet可能会将请求转发给其它的Servlet处理。全部处理完,请求结果通过HttpServletResponse对象返回给浏览器。

当Servlet装载和实例化以后,Servlet会调用init()方法,进行初始化。Servlet处于服务状态。在整个生命周期中,init()执行一次。接收请求时,会调用service()方法,当Servlet不再使用,容器销毁Servlet之前会调用destroy()方法。destroy()方法中做一些资源释放和日志输出的操作。 

init()不需要重载,只在需要初始化时做一些操作时才需要重载,建议重载无参的init()方法,不用调用super.init()方法,有参的init()必须调用父类的init()方法。

使用Servlet实现简单的登陆

login.jsp如下:

<%=request.getContextPath()%>/login">
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

新建一个LoginServlet:

public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String password = req.getParameter("password"); //System.out.println("用户名=" + username); //System.out.println("密码=" + password); String forward = null; //这里简单判断用户名来跳转成功和失败页面 if("ben.deng".equals(username)){ forward = "success.jsp"; //这种跳转不会带请求的参数信息,只在响应头中的location中指定了跳转页面。但可以进入其他应用的页面 //resp.sendRedirect("success.jsp"); }else{ forward = "fail.jsp"; //resp.sendRedirect("fail.jsp"); } //请求转发,可以请求参数带给转发的页面。但只限于应用内的页面。 RequestDispatcher dispatcher = req.getRequestDispatcher(forward); dispatcher.forward(req,resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override public void init() throws ServletException { System.out.println("login init()"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

web.xml配置:

 
login
com.ben.servlet.LoginServlet
login
/login
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Servlet过滤器

创建一个过滤器:

public class MyFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { System.out.println("doFilter..."); chain.doFilter(req, resp); } public void init(FilterConfig config) throws ServletException { System.out.println("filter init():" + config.getInitParameter("paramKey")); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

和Servlet一样,需要在web.xml中配置:

 
MyFilter
com.ben.filter.MyFilter
paramKey
paramValue
MyFilter
/*
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在一个web应用中,可以有多个Filter,多个Filter的执行顺序是和web.xml中配置的顺序是一致的。

过滤器之编码转换

在doGet或doPost方法中返回一串有中文的字符串,浏览器很多时候会显示乱码。这时我们可以在过滤器中进行处理。

String charEncoding = "UTF-8"; public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { if(!charEncoding.equals(req.getCharacterEncoding())){ req.setCharacterEncoding(charEncoding); } resp.setCharacterEncoding(charEncoding); chain.doFilter(req, resp); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

过滤器之权限校验

新建一个权限校验过滤器:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) req; String loginStatus = (String) request.getSession().getAttribute("login"); if (loginStatus != null && "success".equals(loginStatus)) { chain.doFilter(req, resp); } else { String reqPath = request.getServletPath(); if (!reqPath.contains("login")) { //System.out.println("您尚未登陆"); RequestDispatcher rd = request.getRequestDispatcher("login.jsp"); rd.forward(req, resp); }else{ chain.doFilter(req, resp); } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在部署描述符中注册过滤器:

AuthFilter
com.ben.filter.AuthFilter
AuthFilter
/*
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上述代码示例中是将登陆成功后再session中设置一个login属性为success,在其他非login/login.jsp等页面中判断是否有这个session,没有或值不对(比如登录失败设置的其他值),则要求跳转到登录界面。从而实现一个简单的权限校验过滤。

转载于:https://www.cnblogs.com/xyou/p/6993399.html

你可能感兴趣的文章
Android MVC之我的实现
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
关于批处理-1
查看>>
Tomcat部署Web应用方法总结
查看>>
Python3 django2.0 字段加密 解密 AES
查看>>
CCNA实验之:网络地址转换(NAT)实验
查看>>
计算机网络原理笔记-停止等待协议
查看>>
确定当前记录和下一条记录之间相差的天数
查看>>
sql语句返回主键SCOPE_IDENTITY()
查看>>
机器学习开源项目精选TOP30
查看>>
iOS开发-邮件发送
查看>>
/etc/resolv.conf文件详解
查看>>
【转】VC的MFC中重绘函数的使用总结(整理)
查看>>
JQuery日记_5.13 Sizzle选择器(六)选择器的效率
查看>>
oracle查看经常使用的系统信息
查看>>
Django_4_视图
查看>>
Linux的netstat命令使用
查看>>
lvm讲解,磁盘故障小案例
查看>>
大快网站:如何选择正确的hadoop版本
查看>>