一、JSP:java server page
(一)动态web技术:
java+html
1、JSP脚本元素:
(1)jsp声明:<%! %> 全局编码和方法的声明
(2)jsp表达式:<%= %> 输出指定的变量、数据到浏览器
(3)jsp脚本:<% %> 编写合法的java代码
2、JSP指令元素:
(1)page
语法:<%@ page 属性1=value1%>
常用属性:
contentType:响应数据的类型和编码
contentType="text/html;charset=utf-8"\
pageEncoding:页面编码,如果和charset同时存在优先使用pageEncoding
errorPage:指定当前页面发生错误时跳转的页面
isErrorPage:标示该页面是否为错误页面,true(可以使用exception)
import:导入其他类 唯一一个能在page指令中出现多次的属性
import="com.bdyc.po.User"
import="com.bdyc.po.*"
import="com.bdyc.po.*,java.util.*"
language:指定jsp中支持的脚本语言 java
session:true 页面可以使用session内置对象,false 不行
(2)include
语法:静态引入(原样拷贝),先引入再编译(先将页面拷贝到本页面再统一转换编译) 编译后会形成一个文件
<%@ include file="path" %>
作用:用来导入其他的页面内容到本页面
弊端:只要有一个引入的子页面发生改变,系统就会重写编写该文件
好处:只要一个文件
3、JSP动作元素:
(1)jsp:include
语法:动态引入,先编译再引入(先将子页面转换编译,再将子页面编译后结果引入) 会形成多个文件
作用:引入片段页面
弊端:产生多个文件
好处:
改变子页面不会影响到主页面
可以再引入子页面是为子页面传入自定义参数
(2)jsp:param
该标签不能单独使用,一般和jsp:include结合使用用来给子页面传递参数
<%=request.getParameter(name);接受页面参数
(3)jsp:forward(了解)
语法:
作用:将页面转发到指定页面地址
转发:地址栏不变,内容区为其他页面
(4)jsp:useBean
(5)jsp:setProperty
4、JSP内置对象:(9大内置)
JSP页面内部已经存在的对象,JSP页面内部自带的对象可以直接使用 (js内置:Date window document)
ctrl+shift+t:查看源码
(1)out: 类似<%= %>
类型:javax.servlet.jsp.JspWriter extends Writer(输出流:客户端浏览器)
作用域:page(当前页面有效,一个页面有一个out对象)
常用方法:
print(Object obj):输出任何类型数据到客户端浏览器
write(String str):输出字符到客户端浏览器
(2)page(了解)
类型 :java.lang.Object javax.servlet.jsp.HttpJspPage
作用域:page
(3)request
类型:javax.servlet.http.HttpServletRequest
作用域:request 一次请求(浏览器地址栏只要不变)
常用方法:
String value = request.getParameter(name):接受页面一个参数值,根据参数名出去对应的参数值
String[] values = request.getParameterValues(name):根据参数名出去对应的参数值,接受页面一组参数值(checkbox select)
reqeust.getRequestDispatcher(path).forward(request,response):将页面"转发"到目标地址
request.setAttribute(name,value):向request作用域中添加额外属性
request.getAttribute(name):从request作用域中获取指定属性值
request.setCharacterEncoding("utf-8"):设置请求编码,解决POST请求中文乱码问题
(4)response
类型:javax.servlet.http.HttpServletResponse
作用域:response 一次请求(浏览器地址栏只要不变)
常用方法:
response.setRedirect(path): 将页面"重定向"到目标地址
重定向特点:
1、地址栏改变
2、发送2次请求:response.setRedirect("02.jsp");
①、告诉服务我要02.jsp地址,服务器讲02.jsp页面地址响应回来
②、告诉服务我要02.jsp内容,服务器讲02.jsp页面内容响应回来
response.setCharacterEncoding("utf-8"):设置响应数据编码
(5)session:
类型:javax.servlet.http.HttpSesssion
作用域:一次会话(只要浏览器不关闭) 用来存储用户的状态信息
常用方法:
session.getId():获取sessionId
session.isNew():判断session是否是新建的
session.setAttribute(key,value):向session作用域对象中添加属性值
session.getAttribute(key):从session作用域中的获取值
session.removeAttriute(key):从session作用域中的删除某个属性值
session.setMaxInactiveInteaval(ms):设置session的最大失效时间,默认30分钟 20分钟=60*1000*20
session.invalidate():销毁session(手动终止会话方式)
session的工作原理:
当第一次访问jsp页面时系统会创建一个新的session对象,并在给浏览器响应信息时将JSESSIONID值同时通过cookie形式
传输到浏览器,浏览器保存到本地磁盘(默认保存时间为浏览器关闭)。
当你在没有关闭浏览器的时候再次向服务器发送请求时,浏览器会自动将之前的JSESSIONID存放在请求头中一并发送给服务器
服务器接受到对应的JSESSIONID,检查在session池中是否有对应id的session对象,如果有直接返回对象使用。如果没有
重新创建新的session对象响应给浏览器。
不是浏览器不关闭一定就会获取到上一个session对象,还有看服务中session池的对象是否已经销毁。
session对象销毁的方式只要以下两种:
1、sesion的失效时间到了自动销毁
2、手动调用invalidate()方法销毁。
类型:javax.servlet.ServletContext
作用域:一次服务关闭(只要服务器tomcat不关闭,对象一直存在)
常用方法:
application.setAttribute(key,value):
application.getAttribute(key,value):
类型:javax.servlet.ServletConfig
作用域:page
常用方法:
config.getInitParameter(name):
config.getInitParameterValues():
(8)pageContext
类型:javax.servlet.jsp.PageContext
作用域:page
常用方法:
pageContext.getRequest()
pageContext.getResponse();
...
pageContext.setAttribute(key,value):
pageContext.getAttribute(key,value):
类型:java.lang.Exception
作用域:page
常用方法:
exception.getMessage():获取异常信息
exception.printStackTrace():打印异常堆栈信息到控制台
**总结4大作用域:
page:当前页面有效
request:一次请求有效(地址栏不变) --保存业务数据
session:一次会话有效(浏览关闭) --保存用户状态信息(一定不能保存业务数据:用户列表 部门类别 商品信息)
application:一次服务器关闭 --保存不经常改变的数据:系统导航
二、请求方式:get、post
1、post:
参数不会拼接到地址栏,会隐藏到http协议体中传递到后台服务器
安全性相对高
参数大小无限制
效率相对低
设置form表单的请求方式:method="post"
2、get
参数会拼接在地址栏中
安全性相对低
参数大小有限制
效率相对高
设置form表单的请求方式:method="get"
超链接请求
直接在地址栏输入地址的请求方式
如何使用:
如果考虑到效率,且没有安全性时首选get
上传:post
参数传递:
后台接受方式:request.getParameter(name) request.getParameterValues(name)
1、使用form表单向后台发送参数
2、使用地址栏拼接形式:
http://localhost:8080/javaWEB06/loginHandle.jsp?username=admin&password=admin123
第一个参数使用?隔开,其它参数使用&隔开
乱码问题解决:
get请求乱码:
原因:get请求默认使用的是tomcat服务器的编码(iso8859-1)
解决方案:
1、系统tomcat的默认编码:utf-8 修改/conf/server.xml
connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8"/> 2、手动解决 username = new String(username.getBytes("iso8859-1"),"utf-8"); post请求乱码: 解决方案:request.setCharacterEncoding("utf-8"); 三、补充:错误页面处理方式 1、为可能发生错误的页面配置:errorPage="page/error/500.jsp" 2、在web.xml中配置: 四、Servlet主要功能: 1、接受页面参数 JSP: request.getParameter(name): 2、调用业务逻辑(service) 3、负责页面跳转(转发和重定向) JSP: response.sendRedirect(path) request.getRequestDispatcher(path).forward(request,response) 单例设计模式: 自始至终只要一个对象被创建 1、构造方法私有化 2、提供公有静态成员方法实例化对象 3、私有静态本类类型的变量 懒汉式: //单例设计模式:懒汉式 public class User { //私有静态本类类型变量 private static User user;//null //私有构造 private User(){ } //公有静态方法:实例化对象 public static User newInstance(){ if(user == null){ user = new User(); } return user; } } 饿汉式: //单例设计模式:饿汉式 public class User1 { //私有静态本类类型变量 private static User1 user = new User1();//null //私有构造 private User1(){ } //公有静态方法:实例化对象 public static User1 newInstance(){ return user; } } Servlet对象是单例。 在servlet类中能出现可以被修改的成员变量吗? Servlet是在多线程环境运行时,那就必须要考虑线程安全问题: 1、多线程 2、共享一个资源 3、对共享资源进行了:修改操作 如何解决:只要将上述条件中的任何一个失效 Servlet解决线程安全问题(避免线程安全问题出现)方案: 不要在servlet中出现可以被修改的成员变量。 (一)编写servlet步骤: 1、新建一个类实现Servlet接口 2、配置web.xml: 3、servlet过滤器的API:Filter、FilterChain、FilterConfig 4、过滤器三个方法:①init:web容器调用此方法一次 ②doFilter:发送请求时调用 ③destory 5、生命周期的四个阶段: 1>实例化:web容器在部署应用程序时对所有过滤器进行实例化,web容器回调它的无参构造; 2>初始化:实例化完成之后,马上进行初始化工作,web容器回调init()方法,执行一次; 3>过滤:请求路径匹配过滤器的URL映射时,web容器回调doFilter()方法,每次请求都执行的主要的方法; 4>销毁:web容器在卸载web应用程序前,web容器回调destory()方法。 如何编写一个监听器: 1、新建一个类实现ServletContextListener、ServletRequestListener、HttpSessionListener...接口 public class MyListener implements ServletRequestListener{ @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("request对象销毁"); } @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("request对象创建"); } } 2、web.xml配置监听器 必须在filter和servlet配置之前 3、Listener的初始化比filter和servlet都优先,而销毁比他们都慢。 随着web应用的启动而启动,只初始化一次,随web应用的停止而销毁 七、拦截器和过滤器的区别 1、拦截器是基于java的反射机制的,而过滤器是基于函数回调 2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用 4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能 5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次 执行顺序 :过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。 个人认为过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理); 过滤通过后,拦截器将检查用户提交数据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action; Action处理完成返回后,拦截器还可以做其他过程,再向上返回到过滤器的后续操作。