java
session
- 一次会话,如果关闭浏览器就会释放本次session,一个服务器可以有多个session,但是一个客户端只能有一个session,当getSession()时才会创建session,如果不操作页面,也就是当前session有30分钟不活动了那么就会让session自动释放,底层的原理是基于cookie的
jsp三大指令
- page
<%@page ....%>
-
language 编译后的语言类型
-
info 信息
-
errorPage 如果页面发生错误那么就转跳到指定页面
-
-
isErrorPage
- 当设置此页面为
true
时返回的状态码为500 - error-page error-code location exception-type location
- 如果设置为true那么可以用九大内置对象的exception
- 当设置此页面为
-
pageEncoding
-
contentType
-
autoFlush 缓冲区满自动刷新
-
buffer 设置缓冲区大小
-
isELIgnored 是否忽略el表达式
-
isThreadSafe 是否并发访问默认false
-
session 是否支持session
- 9大内置对象中可能无法使用的就是session和exception
-
extends 让jsp生产的servlet去继承该属性指定的类!
-
- include <%@include …%>
导入时记得清除干净导入的jsp文件,防止重复的源文件
- 属性file用于指定x.jsp
- 与RequestDispatcher的include相同
- 由于是先合并,并不是动态的包含,那么处理jsp就如同处理文本一样, 如果使用变量是无法确认的,
因此不能file属性不能设置为变量
include
编译时合并RequestDispatcher
运行时合并
- 由于是先合并,并不是动态的包含,那么处理jsp就如同处理文本一样, 如果使用变量是无法确认的,
- 如果存在相同的程序块,那么么我们可以把这个程序块进行抽离,并使用include导入,由于是编译时合并无法使用变量
- taglib 导入标签库
- prefix: 指定标签库在本页面中的前缀
- uri: 指定位置
jsp九大内置对象
- out 向客户端发送文本
- config serveletConfig
- page servelet->this
- pageContext
- 只能获取本页面的域
- 一个可以获取其他8个内置对象
- .findAttribute() 可以查找其他域,从小域开始查找,返回为字符串
- 查找顺序依次是 page,request,session,application
- .setAttribute(“xxx”, “XXX”, pageContext .SESSION_SCOPE) 代理其他域对象
- 域对象有setAttribute,getXXXX,removeXXX
- exception
- request
- response
- application ServeletContext
- session
jsp动作标签
<jsp:include>
与 RequestDispatcher的include一样<jsp:include>
是动态的包含<%@include ...%>
是静态包含- 简而言之就是动态的生成的是多个编译后的文件.class,而静态包含生成的则是生成的一个.class
<jsp:forward>
与 RequestDispatcher的forward一样<jsp:param>
作为子标签给include和forward传参
javaBean
- 规范
- 必须有一个构造方法
- 属性必须有个get/set方法,如果只有get方法那么这个属性就是只读属性
- 属性可以没有成员,直接返回数据也算属性
- 工具下载地址
- https://commons.apache.org/proper/commons-logging/download_logging.cgi
- http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi
- 基于java原生反射和自行进行简单实现一个BeanUtils
@Test
public void Test() throws Exception {
// 通过字符串获取类
Class clazz = Class.forName("cn.yxhpy.domain.Person");
// 通过自省获取类的beanInfo
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
@SuppressWarnings("deprecation")
// 实例化类
Object object = clazz.newInstance();
// 获取属性描述符们
PropertyDescriptor[] pd = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : pd) {
// 可以获取到读方法,对应到类里的setXxx方法
Method wrMethod = propertyDescriptor.getWriteMethod();
if (wrMethod!=null)
{
System.out.println(wrMethod.getName());
if (wrMethod.getParameterTypes()[0].getName() == "java.lang.String") {
wrMethod.invoke(object, "111");
}
else {
wrMethod.invoke(object, 1111);
}
}
}
for (PropertyDescriptor propertyDescriptor : pd) {
// 可以获取到读方法,对应到类里的getXxx方法
Method wrMethod = propertyDescriptor.getReadMethod();
if (wrMethod!=null)
{
System.out.println(wrMethod.getName());
System.out.println(wrMethod.invoke(object));
}
}
}
- 使用BeanUtils自带的方法来实现给类属性赋值, 原类处理不存在属性时非常的温和,而且可以自己将字符串转化为数字
@Test
public void Test1() throws Exception {
Class clazz = Class.forName("cn.yxhpy.domain.Person");
Object bean = clazz.newInstance();
BeanUtils.setProperty(bean, "name", "yxhpy");
BeanUtils.setProperty(bean, "age", 12);
BeanUtils.setProperty(bean, "gender", "男");
System.out.println(bean);
Map<String, String> map = new HashMap<String, String>();
map.put("name", "yxhpy1");
map.put("age", "123");
map.put("gender", "男1");
BeanUtils.populate(bean, map);
System.out.println(bean);
}
- jsp相关标签
<jsp:useBean>
- 创建或查询bean
<jsp:setProperty>
- 设置属性
<jsp:getProperty>
- 获取属性
- 具体代码
<jsp:useBean id="user" class="cn.yxhpy.domain.Person" scope="page"></jsp:useBean> <jsp:setProperty property="name" name="user" value="yxhpy"/> <jsp:setProperty property="age" name="user" value="21"/> <jsp:setProperty property="gender" name="user" value="男"/> <jsp:getProperty property="name" name="user"/> <jsp:getProperty property="age" name="user"/> <jsp:getProperty property="gender" name="user"/>
EL
- 有了上面的Bean的规范那么我们就可以通过EL很快的获得实例的属性
<%
// 这里就不使用反射了
Person person = new Person();
person.setAddress("成都");
person.setAge(18);
person.setName("yxhpy");
session.setAttribute("user", person);
%>
<h1>UserInfo:</h1>
${sessionScope.user.name }
${sessionScope.user.age }
${sessionScope.user.address }
- EL的11个内置对象
- pageScope
- requestScope
- sessionScope
- applicationScope
- 前四个都是map但在el中可以使用.的方式获取属性值
- param
- paramValues
- header
- headerValues
- initParam 获取web.xml初始化参数
- cookie: Map<String, Cookie>
- pageContext 一个顶十个
- EL内置的函数
- 导入
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> ${fn:length("1111111") }
fn:contains(string, substring) 如果参数string中包含参数substring,返回true
fn:containsIgnoreCase(string, substring) 如果参数string中包含参数substring(忽略大小写),返回true
fn:endsWith(string, suffix) 如果参数 string 以参数suffix结尾,返回true
fn:escapeXml(string) 将有特殊意义的XML (和HTML)转换为对应的XML character entity code,并返回
fn:indexOf(string, substring) 返回参数substring在参数string中第一次出现的位置
fn:join(array, separator) 将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。
fn:length(item) 返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。如果是String类型,返回值是String中的字符数。
fn:replace(string, before, after) 返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果
fn:split(string, separator) 返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素
fn:startsWith(string, prefix) 如果参数string以参数prefix开头,返回true
fn:substring(string, begin, end) 返回参数string部分字符串, 从参数begin开始到参数end位置,包括end位置的字符
fn:substringAfter(string, substring) 返回参数substring在参数string中后面的那一部分字符串
fn:substringBefore(string, substring) 返回参数substring在参数string中前面的那一部分字符串
fn:toLowerCase(string) 将参数string所有的字符变为小写,并将其返回
fn:toUpperCase(string) 将参数string所有的字符变为大写,并将其返回
fn:trim(string) 去除参数string 首尾的空格,并将其返回
- 自定义el
- 自定义一个类实现的是静态函数
package cn.yxhpy.utils;
public class Functions {
public static String display() {
return "hello world";
}
}
- 新建 xxx.tld
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>YXHPY's Lib</description>
<display-name>yxhpy function</display-name>
<tlib-version>1.0</tlib-version>
<short-name>tf</short-name>
<uri>/WEB-INF/utils.tld</uri>
<function>
<description>
display hello world
</description>
<name>display</name>
<function-class>cn.yxhpy.utils.Functions</function-class>
<function-signature>java.lang.String display()</function-signature>
</function>
</taglib>
- 导入jsp
<%@taglib prefix="fn" uri="/WEB-INF/utils.tld"%>
// 使用
${fn:display() }
4.出错到web.xml
添加
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/utils.tld</taglib-uri>
<taglib-location>/WEB-INF/utils.tld</taglib-location>
</taglib>
</jsp-config>
JSTL
- 导入
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
- c:out
escapeXml
可以将原本的前端代码进行格式化,防止xss - c:set 向某个域某个键设置某个值
- c:url 获取到项目名后与value="xx"进行拼接后展示到前端
- c:remove 删除某个域的某个键和值
- c:if 如果满足test="true"那么就展示
empty
可以判断是否为空 - c:choose c:when c:otherwise 和if else if else 差不多
- c:forEach 循环数组和列表
- c:out
- 导入
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
- fmt:formatDate 格式化输出时间
- fmt:formatNumber 格式化输出数字
0.00
形式用于会补位,而#.##
不会补位
<body>
<%--
request.setAttribute("script", "<script type='text/javascript'>alert('hello world!')</script>");--%>
<c:set var="script" scope="request" value="1111<script type='text/javascript'>alert('hello world!')</script>"></c:set>
<c:out value="${script }" escapeXml="true" default="hello world!"></c:out>
<c:remove var="script" scope="request"/>
<c:url value="/index.jsp">
<c:param name="username" value="张三"></c:param>
</c:url>
<p>c:url</p>
<a href='<c:url value="/index.jsp"></c:url>'>点我</a>
<p>c:if</p>
<c:if test="true">显示c:if</c:if>
<p>choose</p>
相当于if(){} else if(){} else{}
<c:set scope="request" var="choose" value="18"></c:set>
<c:choose>
<c:when test="${requestScope.choose == 18}">18</c:when>
<c:when test="${requestScope.choose == 18}">18</c:when>
<c:when test="${requestScope.choose == 221}">221</c:when>
<c:when test="${requestScope.choose == 12}">12</c:when>
<c:when test="${requestScope.choose == 32}">32</c:when>
<c:otherwise>not find</c:otherwise>
</c:choose>
<p>empty</p>
<c:if test="${!empty param.name}">
<h1>${param.name }</h1>
</c:if>
<p>forEach</p>
<c:forEach var="i" begin="0" end="10">
${i }
</c:forEach>
<br>
<%
Integer list[] = new Integer[]{1,2,3,4,5};
request.setAttribute("list", list);
Cookie[] cookie = request.getCookies();
request.setAttribute("cookie", cookie);
%>
<c:forEach items="${list }" var="item">
${item }
</c:forEach>
<br>
<c:forEach items="${requestScope }" var="item" varStatus="vs">
${vs.index }:${vs.count }:${vs.last }:${vs.first }:${item.key }:${item.value }<br>
</c:forEach>
<br>
<%
ArrayList<String> list2 = new ArrayList<String>();
list2.add("一");
list2.add("二");
list2.add("三");
pageContext.setAttribute("list2", list2);
%>
<c:forEach items="${list2 }" var="item">
${item }
</c:forEach>
<h1>Fmt</h1>
<%
Date date = new Date();
request.setAttribute("date", date);
%>
<fmt:formatDate value="${requestScope.date }" pattern="yyyy-MM-dd HH:mm:ss"/><br>
<%
request.setAttribute("num1", 10);
%>
<fmt:formatNumber pattern="#.##" value="${requestScope.num1 }"/><br>
<fmt:formatNumber pattern="0.00" value="${requestScope.num1 }"/>
</body>
自定义标签
- 增加一个tag类 并
implements
SimpleTag
或者直接使用extends
SampleTagSupport
就无需自己接受pageContext
和body
只需要自己实现一个dotag
package cb.yxhpy.tag;
import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;
public class MyTag implements SimpleTag{
private PageContext pageContext;
private JspFragment body;
public void doTag() throws JspException, IOException {
pageContext.getOut().print("hello world!");
}
public JspTag getParent() {
// TODO Auto-generated method stub
return null;
}
public void setJspContext(JspContext pc) {
this.pageContext = (PageContext) pc;
}
public void setJspBody(JspFragment jspBody) {
this.body = jspBody;
}
public void setParent(JspTag parent) {
// TODO Auto-generated method stub
}
}
- 写一个tld文件
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<display-name>yxhpy tag</display-name>
<tlib-version>1.0</tlib-version>
<short-name>yxhtg</short-name>
<uri>/WEB-INF/tlds/mytlds.tld</uri>
<tag>
<name>showHello</name>
<tag-class>cb.yxhpy.tag.MyTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
- 调用
<%@taglib prefix="yxhtg" uri="/WEB-INF/tlds/mytlds.tld"%>
<yxhtg:showHello/>
- 如果显示无法找到对应的tag回看自定义
EL
- 使用
scriptless
设计闭环标签
package cb.yxhpy.tag;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class MyTag1 extends SimpleTagSupport{
public void doTag() throws JspException, IOException {
Writer out = this.getJspContext().getOut();
out.write("***********");
this.getJspBody().invoke(out);
out.write("***********");
}
}
<tag>
<name>testSriptLess</name>
<tag-class>cb.yxhpy.tag.MyTag1</tag-class>
<body-content>scriptless</body-content>
</tag>
<yxhtg:testSriptLess>
hello world!
</yxhtg:testSriptLess>
- 抛出异常后
skipPageException
下面内容全部消失
package cb.yxhpy.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class MyTag2 extends SimpleTagSupport{
public void doTag() throws JspException, IOException {
throw new SkipPageException("只显示我哈哈哈,下面全部消失");
}
}
此标签下面的内容全部消失不见
7. 带属性的tag
package cb.yxhpy.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class MyTag3 extends SimpleTagSupport{
private boolean test;
@Override
public void doTag() throws JspException, IOException {
// null == getJspContext().getOut()
if (this.test)
getJspBody().invoke(null);
}
public void setTest(boolean test) {
// TODO Auto-generated method stub
this.test = test;
}
}
<tag>
<name>testSetAttr</name>
<tag-class>cb.yxhpy.tag.MyTag3</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>test</name>
<required>true</required> <!--是否可以为空-->
<rtexprvalue>true</rtexprvalue> <!--是否可以使用el表达式-->
</attribute>
</tag>
<yxhtg:testSetAttr test="false">
hello world!!!!!!
</yxhtg:testSetAttr>
tomcat服务器配置
- context.xml
reloadable="true"
修改项目时可以自动更新项目
- web.xml
<error-page>
// 错误的状态码
<error-code></error-code>
// 错误的转跳地址
<location></location>
</error-page>