除了servlet规范,还有filter,listener。filter和servlet相似,但是在servlet之前执行,主要区别是有一个FilterChain接口可以执行拦截方法。
1 import java.io.IOException; 2 import javax.servlet.Filter; 3 import javax.servlet.FilterChain; 4 import javax.servlet.FilterConfig; 5 import javax.servlet.ServletException; 6 import javax.servlet.ServletRequest; 7 import javax.servlet.ServletResponse; 8 import javax.servlet.annotation.WebFilter; 9 /*Filter和Servlet结构相似,有两个生命周期方法和一个执行任务的方法,且配置格式相同 10 * 注意url的不同,Filter的url是要拦截的url,而Servlet的url是访问时使用的url 11 * 当用户访问相应的url路径时,会执行Filter的doFilter() 12 * 13 * 注意:下面的@WebFilter部分是Servlet3的新特性,是过滤器的注解,不需要在web.xml进行配置,简化的配置文件信息 14 */ 15 @WebFilter({ "/BFilter", "/AServlet" }) 16 public class AFilter implements Filter { 17 18 /*这里的参数FilterConfig对象和ServletConfig相似 19 */ 20 public void destroy() { 21 System.out.println("A拦截器死亡"); 22 } 23 24 /*下面的参数FilterChain对象只有一个方法doFilter(), 25 * 该方法可以执行目标资源(即被拦截的资源),也可以执行下一个拦截器(如果有的话,像一条链一样) 26 */ 27 public void doFilter(ServletRequest request, ServletResponse response, 28 FilterChain chain) throws IOException, ServletException { 29 System.out.println("A成功拦截"); 30 chain.doFilter(request, response); //执行这句话就可以执行被拦截的url要进行的操作 31 System.out.println("A执行完上面在回来"); 32 } 33 34 public void init(FilterConfig fConfig) throws ServletException { 35 System.out.println("hahahah...,A拦截器出生"); 36 } 37 38 }
listener和它们稍有不同,是对特定事件的监听和处理。
1 import javax.servlet.ServletContextAttributeEvent; 2 import javax.servlet.ServletContextAttributeListener; 3 import javax.servlet.ServletContextEvent; 4 import javax.servlet.ServletContextListener; 5 import javax.servlet.annotation.WebListener; 6 import javax.servlet.http.HttpSessionBindingEvent; 7 import javax.servlet.http.HttpSessionBindingListener; 8 9 /*listener监听器也是Javaweb三大组件之一,也需要在web.xml中进行配置 10 * 监听器就是用来对特定事件进行监听,并作出相应的行为,所以监听器都是接口,需要用户自己完成对行为的定义 11 * Javaweb中有8个监听器,其中有6个对3大域(ServletContext/HttpSession/ServletResquset)进行监听, 12 * 其中一个监听域的生命周期,一个监听域的属性 13 * 只要实现相应接口即可完成监听,下面就是对ServletContext生命周期的监听(即对init()和destroy()监听) 14 */ 15 @WebListener 16 public class Dlistener implements ServletContextListener, ServletContextAttributeListener,HttpSessionBindingListener{ 17 public Dlistener() { 18 } 19 20 /*监听器的另一个重要的方面就是事件对象,这是自动传入的,可以对事件进行分析然后采取不同的处理方式 21 * 在生命周期监听器中,事件对象的主要方法是获取相应域对象 22 */ 23 @Override 24 public void contextDestroyed(ServletContextEvent arg0) { 25 System.out.println("死亡!"); 26 } 27 28 @Override 29 public void contextInitialized(ServletContextEvent arg0) { 30 System.out.println("出生!"); 31 } 32 33 34 /*属性监听器:用于对属性的设置/重置/移除等事件的监听, 35 * 这种监听器的事件对象可以获取操作的属性的键值对, 36 */ 37 public void attributeAdded(ServletContextAttributeEvent event) { 38 System.out.println("您向application中添加了一个名为" + event.getName() + ", 值为:" 39 + event.getValue() + "的属性"); 40 } 41 42 //注意重置时,事件对象获取的是被操作的属性键值对(即原来的),同时可以通过域对象获取新的键值对 43 public void attributeReplaced(ServletContextAttributeEvent event) { 44 System.out.println(event.getName() + "=" + event.getValue() + ", " 45 + event.getServletContext().getAttribute(event.getName())); 46 } 47 48 public void attributeRemoved(ServletContextAttributeEvent event) { 49 System.out.println(event.getName() + "=" + event.getValue()); 50 } 51 52 /*8个监听器还有两个,可称为感知监听器,都与HttpSession有关 53 * 特点是:1、添加在javabean中而非域中,2、不需在web.xml中配置 54 * 55 * 一个是HttpSessionBindingListener,绑定在一个JavaBean中,可以使其感知是否被session添加/移除 56 * 另一个是HttpSessionActivationListener,同样绑定在JavaBean中,可以感知是否绑定session并且这个 57 * session是否钝化或重新活化 58 */ 59 private String username; 60 private String password; 61 public String getUsername() { 62 return username; 63 } 64 public void setUsername(String username) { 65 this.username = username; 66 } 67 public String getPassword() { 68 return password; 69 } 70 public void setPassword(String password) { 71 this.password = password; 72 } 73 74 public Dlistener(String username, String password) { 75 super(); 76 this.username = username; 77 this.password = password; 78 } 79 @Override 80 public String toString() { 81 return "User [username=" + username + ", password=" + password + "]"; 82 } 83 84 //下面两个是HttpSessionBindingListener监听器方法,感应该javabean是否被session保存和移除 85 @Override 86 public void valueBound(HttpSessionBindingEvent event) { 87 System.out.println("啊~,session添加了我!"); 88 } 89 @Override 90 public void valueUnbound(HttpSessionBindingEvent event) { 91 System.out.println("哇哇哇~,无情的session抛弃了我!"); 92 } 93 }
JSP是Java server pages,是java的view层即响应的基础,=html+Java代码+Java指令,
在第一次访问JSP文件时,服务器会将其转换为Java文件,并编译为class字节码文件,然后创建对象。这个对象内部会生成一些对象,包括域对象;也会对java指令进行解释执行,并且对参数进行赋值,最后将执行之后的html代码相应给客户端。
Java指令,包括三种:
1、page指令,是对文件的全局设置,比如响应的编码等<%@page ...%>
2、include指令,静态包含引入文件,<%@include ...%>
3、taglib,导入标签库.最基础使用的是JSTL和fmt标签库。其中JSTL标签库是重点:可以进行判断,循环等复杂逻辑。注意:使用JSTL标签库需要导入相应jar包,myeclipse中已经默认添加,所以可以直接使用。
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%-- 3 这里使用的是JSTL的核心库标签:core,也被称为c标签,前缀通常使用c 4 --%> 5 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 6 <%-- 7 这里使用的是JSTL的格式化标签库:fmt, 8 --%> 9 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 10 <% 11 String path = request.getContextPath(); 12 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 13 %> 14 15 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 16 <html> 17 <head> 18 <base href="<%=basePath%>"> 19 20 <title>My JSP 'JSTL.jsp' starting page</title> 21 22 <meta http-equiv="pragma" content="no-cache"> 23 <meta http-equiv="cache-control" content="no-cache"> 24 <meta http-equiv="expires" content="0"> 25 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 26 <meta http-equiv="description" content="This is my page"> 27 <!-- 28 <link rel="stylesheet" type="text/css" href="styles.css"> 29 --> 30 31 </head> 32 33 <body> 34 <%--下面三个标签是用于设置/输出/移除域中属性,可以设置指定域,设置时默认对特殊标签进行转义,默认域为page--%> 35 <c:set var="xxx" value="<script>alter('hello');</script>" scope="page"/> 36 <c:out value="${xxx}" /><br/> 37 <c:remove var="xxx" scope="page"/> 38 <c:out value="${xxx}" default="该值不存在或已被删除"/><br/> 39 40 <%--下面是两种生成url的方式比较 --%> 41 ${pageContext.request.contextPath}/Aservlet<br/> 42 <c:url value="/AServlet"> 43 <c:param name="username" value="张三"></c:param> 44 </c:url> 45 <br/> 46 47 <%--JSTL标签还可以替换判断语句和循环语, 48 判断语句分两种:1、单个判断,2、多个判断 49 --%> 50 <%-- 51 注意:判断是否为空时,格式为not empty ***/empty *** 52 --%> 53 <c:if test="${not empty xxx}"> 54 hello<br/> 55 </c:if> 56 <c:set var="fen" value="60" /> 57 <c:choose> 58 <c:when test="${fen>100||fen<0}"> 59 错误的分数<br/> 60 </c:when> 61 <c:when test="${fen<60}"> 62 不及格<br/> 63 </c:when> 64 <c:when test="${fen>=60}"> 65 及格<br/> 66 </c:when> 67 </c:choose> 68 <%--循环有两种,一种是计数循环;一种是遍历循环,用于集合和数组 --%> 69 <c:forEach var="i" begin="1" end="10" step="2"> 70 ${i}<br/> 71 </c:forEach> 72 <% 73 String[] str={"a","b"}; 74 request.setAttribute("str", str); 75 %> 76 <%--!!!注意下面在items属性值的结束"之前不要有多余的空格,否则会出错--%> 77 <c:forEach items="${requestScope.str}" var="string"> 78 ${string}<br/> 79 </c:forEach> 80 81 <% 82 Date d=new Date(); 83 request.setAttribute("date",d); 84 %> 85 <fmt:formatDate value="${date}" pattern="yyyy-MM-dd HH:mm:ss"/> 86 <br/> 87 </body> 88 </html>
参考:http://www.cnblogs.com/lihuiyy/archive/2012/02/24/2366806.html
java代码是在jsp中运行java程序片段,但是不建议过多使用。
在jsp页面和java代码之间传递数据使用的是四大域对象,在代码中通常通过HttpRequestServlet来获取其他几个域对象,而且这个除了是请求对象本身就是Request域对象,参考:http://www.cnblogs.com/jbelial/archive/2013/07/11/3184928.html。
JavaBean就是一个满足特殊规范的类:(最早用于创建图形化界面时拖拽控件时使用,一个控件对应一个JavaBean类)
参考:http://davidgjy.iteye.com/blog/442749
1 public class Person { 2 /*该类就是一个javabean的示例,规范是: 3 * javaBean的规范: 4 * 1. 必须要有一个默认构造器 5 * 2. 提供get/set方法,如果只有get方法,那么这个属性是只读属性! 6 * 3. 属性:有get/set方法的成员,还可以没有成员,只有get/set方法。属性名称由get/set方法来决定!而不是成员名称! 7 * 4. 方法名称满足一定的规范,那么它就是属性!boolean类型的属性,它的读方法可以是is开头,也可以是get开头! 8 * 9 */ 10 private String username; 11 private int age; 12 private String sex; 13 14 public Person(String username, int age, String sex) { 15 super(); 16 this.username = username; 17 this.age = age; 18 this.sex = sex; 19 } 20 public Person() { 21 super(); 22 } 23 24 //第三条指的是如下面的情况:get后面使用的name,而成员是username时以get后为准, 25 public String getName() { 26 return username; 27 } 28 public void setName(String username) { 29 this.username = username; 30 } 31 public int getAge() { 32 return age; 33 } 34 public void setAge(int age) { 35 this.age = age; 36 } 37 public String getSex() { 38 return sex; 39 } 40 public void setSex(String sex) { 41 this.sex = sex; 42 } 43 //一个属性可以只有get/set方法而没有成员 44 public String getId(){ 45 return "89757"; 46 } 47 48 @Override 49 public String toString() { 50 return "Person [username=" + username + ", age=" + age + ", sex=" + sex + "]"; 51 } 52 53 }
操作JavaBean可以使用内省,内省是基于反射的一种实现,可以获取beaninfo(其中包含对应Javabean的信息),操作流程如下
内省类 --> Bean信息 --> 属性描述符 --> 属性的get/set对应的Method! --- > 可以反射了!
但是apache提供了一个jar包,可以方便的实现上述操作
1 import java.util.HashMap; 2 import java.util.Map; 3 4 import org.apache.commons.beanutils.BeanUtils; 5 import org.junit.Test; 6 7 import cn.dqxst.utils.CommonUtils; 8 9 public class BeanUtilsDemo { 10 /*在myeclipse中使用junit单元测试, 11 * 只要在需要测试的前加 @Test ,注意有大小写区别,就会提示导入测试所需的包 12 */ 13 @Test 14 public void fun1() throws Exception { 15 String className="cn.dqxst.domain.Person"; 16 Class<?> clazz=Class.forName(className); 17 Object bean=clazz.newInstance(); 18 //BeanUtils可以代替繁琐的反省操作,直接对JavaBean操作 19 /*如果某个属性没有设置不会报错, 20 * 注意该类对属性值的处理:都会转换为字符串,然后在赋值时按需要进行转换 21 * 并且在获取属性时,会将其值转换为String类型,可以按需转换 22 */ 23 BeanUtils.setProperty(bean, "name", "张三"); 24 BeanUtils.setProperty(bean, "age", "23"); 25 //如果有多余属性设置则忽略 26 BeanUtils.setProperty(bean, "xxx", "XXX"); 27 28 System.out.println(bean); 29 } 30 31 //将一个Map和一个JavaBean对应,两者包含相同的属性 32 @Test 33 public void fun2() throws Exception{ 34 Map<String,String> map=new HashMap<String, String>(); 35 map.put("name","张三"); 36 map.put("password", "123"); 37 38 User user=new User(); 39 BeanUtils.populate(user, map); 40 41 System.out.println(user); 42 } 43 //这里是使用再次封装的类进行上述操作 44 @Test 45 public void fun3(){ 46 Map<String,String> map=new HashMap<String, String>(); 47 map.put("name","张三"); 48 map.put("password", "123"); 49 50 User user=CommonUtils.toBean(map, User.class); 51 System.out.println(user); 52 } 53 54 }
1 import java.util.Map; 2 import java.util.UUID; 3 4 import org.apache.commons.beanutils.BeanUtils; 5 6 public class CommonUtils { 7 //获取一个32位长的随机大写字串 8 public static String uuid(){ 9 return UUID.randomUUID().toString().replace("-", "").toUpperCase(); 10 } 11 12 //将一个Map集合中的数据封装到一个JavaBean中,两者需要一一对应 13 public static <T> T toBean(Map<String,String> map,Class<T> clazz){ 14 //1、在这里使用try,避免调用者进行重复的错误处理过程 15 try{ 16 //创建指定类型的JavaBean对象 17 T bean=clazz.newInstance(); 18 //调用BeanUtils类进行封装操作 19 BeanUtils.populate(bean, map); 20 //返回封装好的JavaBean对象 21 return bean; 22 }catch(Exception e){ 23 throw new RuntimeException(); 24 } 25 } 26 }