JavaBean规范、EL、JSTL、

一:JavaBean规范:

01.JavaBean的规范

什么是JavaBean:			符合某些设计规范的类.

为什么需要使用JavaBean:   避免代码重复问题,起到功能重复使用.

JavaBean遵循的规范:
		
			1):类必须使用public修饰.
	
			2):必须有公共无参数的构造器.
	
			3):包含属性的操作方法.

简单的JavaBean:	domain,dao,service等等...

复杂的JavaBean:	Panel,Window,Button等(awt,swing).

JavaBean包含的成员:
		
			1):方法
					
			2):事件
		
			3):属性

属性:
		
	1):attribute:XML/HTML标签的属性,在Java中没有attribute的概念,很多人习惯把字段(Field)成之为

				 属性(attribute),这是一种不正确的叫法.
		
	2):property:是由getter/setter方法所决定的.要给JavaBean定义属性,必须提供getter或者setter方法.

				在以后,在框架中操作的基本上都是操作属性而不会操作字段.
	
	注意:在标准情况下(使用Eclipse自动生成getter/setter),字段和属性名相同.

属性的编写规则,其实也就是getter/setter方法的编写规则:
	
获取属性值的方法:readableMethod(getter):
		
			public 数据类型 getXyz(){

				return  字段;
			
			}

			此时属性:xyz就是属性
	
		注意:
			
			1:方法必须使用public修饰.
				
			2:方法必须有返回类型.
	
			3:方法没有参数.
	
			4:如果数据类型是boolean,此时方法不是getXxx,而是isXxx.

设置属性值的方法:writeableMethod(setter):
	
		public void setXyz(数据类型 变量){
		
			字段 = 变量;

		}
			
		注意:
			
			1:方法必须使用public修饰.
				
			2:方法返回类型必须是void.
	
			3:方法必须有参数(因为需要设置传递过来的参数值).
	
		因为,给字段提供getter/setter,没有任何技术含量,所有,我们一般都是使用Eclipse自动生成的.
	
		问题:
			
			字段和属性名字必须相同吗?
				
			有可能存在字段,没有属性,存在属性,没有字段.

02.内省机制

JavaBean的内省机制(自省机制):
	
		目的:通过内省机制,获取和操作JavaBean中的成员信息(方法,事件,属性);

核心类:java.beansIntrospector.

//获取User的属性
public class IntrospectorDemo {

	public static void main(String[] args) throws Exception {
	
		//BeanInfo getBeanInfo(Class beanClass):获取哪一份字节码的JavaBean描述对象
		BeanInfo beanInfo = Introspector.getBeanInfo(User.class,Object.class);
		
		//PropertyDescriptor[] getPropertyDescriptors():获取描述JavaBean所有属性的描述器
		PropertyDescriptor[] pdc = beanInfo.getPropertyDescriptors();
		
		for (PropertyDescriptor pd : pdc) {
		
			String name = pd.getName();//属性名称
			Class type = pd.getPropertyType();//属性类型
			Method getter = pd.getReadMethod();//获取getter方法
			Method setter = pd.getWriteMethod();//获取setter方法
			System.out.println(name+","+type);
			System.out.println(getter);
			System.out.println(setter);
		}
	}
}

03.Lombok—Java代码自动生成

Lombok是什么:

			Lombok是一款小巧的代码生成工具.官方网址:http://projectlombok.org/
				
lombok主要特性有:
	
			自动生成默认的getter/setter方法、自动化的资源管理(通过@Cleanup注解)及注解驱动的异常

		处理等.目前在国外广泛应用.LomBok它和jquery一样,目标是让程序员写更少的代码,以及改进一些

		原始语法中不尽人意的地方.LomBok能做到这一点.既不是用annotations process,也不是用反射.
		
		而是直接黑到了编译过程中.所以对应用效率没有任何影响,我们可以通过反编译class文件进行验证.

为何项目中要引入LomBok(让程序员编写更少的代码):

本人认为主要有以下三点:
	
		1:提高开发效率
	
		2:使代码直观、简洁、明了、减少了大量冗余代码(一般可以节省60%-70%以上的代码)
			
		3:极大减少了后期维护成本

如何安装,如何使用,参考文档

JavaBean其实和Map非常类似:

		属性 = 属性值;
			
		key  = value;

JavaBean和Map的相互转换:

public static void main(String[] args){
	
	Person p = new Person(123L,"乔峰",32);
	Map<String,Object> map = bean2map(p);
	System.out.println(map);
	
	Person obj = map2bean(map, Person.class);
	System.out.println(obj);
}

//把JavaBean对象转换为MAP;
public static Map<String, Object> bean2map(Object bean) throws Exception {

	Map<String, Object> map = new HashMap<String, Object>();
	BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class);
	PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
	for (PropertyDescriptor pd : pds) {
		String propertyName = pd.getName();
		if(propertyName.compareToIgnoreCase("class")==0){
			continue;
		}
		Method getter = pd.getReadMethod();
		Object value = getter!=null? getter.invoke(bean) : null;
		map.put(propertyName, value);
	}
	return map;
}

//把Map对象转换为JavaBean对象.
public static <T>T map2bean( Map<String,Object> map , Class<T> Type){
	
	T obj = type.newInstance();
	BeanInfo beanInfo = Introspector.getBeanInfo(type, Object.class);
	PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
	for(PropertyDescriptor pd : pds){
		String propertyName = pd.getName();
		Object value = map.get(propertyName);
		pd.getWriteMethod().invoke(obj, value);
	}
	return obj;
}

二:EL

04.EL的基本使用

EL:表达式语言

目的:从作用域中获取指定属性名的共享数据.

语法:${属性名},注意属性名没有引号.

没有EL:
	
		<%=pageContext.getAttribute("msg")==null? "":pageContext.findAttribute("msg")%>EL:
		
		${msg}
	
EL从作用域中查询查询指定属性名的共享数据,是有查找顺序的,

按照顺序依次page,request,session,application,寻找共享数据.

05.通过EL获取JavaBean对象中的数据

EL中的内置对象(隐式对象):

$(内置对象.)

下面都是隐式对象:

		param
		
		paramValues
	
		header
		
		headerValues
	
		cookie
	
		initParam

EL中的四大内置的作用域对象

		pageScope
	
		requestScope
		
		sessionScope
	
		applicationScope

获取对象中的属性:

	req.setAttribute("p",person);

	方式一: 使用.	${p.username}
	
	方式二: 使用[]   ${p["username"]}

	我们建议使用方式1,此时就得属性名起一个有意义的英文单词或单词短语.
	
	因为JavaBean和Map很类似.	${p.username},中的username也可以是Map中key的名字.
@Getter		//切记要加Getter注解
public class Person {
	private String username="luck";
	private Integer age = 18;
	private String[] hobbys = {"java","c","girl"};
	private List<String> list = Arrays.asList("list1","list2","list3");
	private Map<String,Object> map = new HashMap<String,Object>(){
		{
			this.put("company","小码哥教育");
			this.put("englishName","see my go");
			this.put("www.xiaoma.com","假域名");
		}
	};
}

@WebServlet("/el")
public class ElServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Person person = new Person();
		req.setAttribute("p", person);
		req.getRequestDispatcher("/el/el.jsp").forward(req, resp);
	}
}
		EL页面
		<br/>${p.username}
		<br/>${p.age}
		<br/>${p.hobbys[2]}
		<br/>${p.list}
		<br/>${p.map.company}
		<br/>${p.map.englishName}
		<br/>${p.map["www.xiaoma.com"]}

06.EL的其他细节

EL的其他:
		
		获取上下文路径:<%=request.getContextPath() %><br/>
		
		获取下下文路径:${pageContext.getRequest().getContextPath()}<br/>
		
		获取下下文路径:${pageContext.request.contextPath}EL中编写我们的运算式:\${1+3/2 }:${1+3/2 }<br/>
		
		可以判断集合是否为空(如果集合中有元素,则不空):
			
		<%
			//向当前page作用域设置共享数据.
			pageContext.setAttribute("list",new java.util.ArrayList());
		%>
		${empty list}
		
		做比较:
		${1 == 1 }
		${1 eq 1 }
	
		从Tomcat7开始,支持在EL中调用方法:${pageContext.getRequest().getContextPath()}

三:JSTL

07.JSTL的概述和准备

JSTL:(Java标准标签库)(JavaServer Pages Standard Tag Library)目前最新的版本为1.3.

	 JSTL是由JCP所制定的标准规范,它主要提供给JavaWeb开发人员一个标准通用的标签函数库.

使用JSTL的准备工作:
	
		1:加入jar包:   standar.jar     jstl.jar
			
		  在Tomcat根\webapps\examples\WEB-INF\lib找到
		
		2:通过JSP的taglib指令,引入标签库.
			
		  <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
		
		  可以引入多个不同类型的标签库!
		
		标签库的使用方法:<c:tagname...>

08.if和choose标签

常用的JSTL标签:
	
		1):条件判断语句.
			
		单条件判断:<c:if/>标签:  
			   
			   <% pageContext.setAttribute("num",30); %>
		
		语法1: 满足条件,就输出标签中的内容:
				
			  <c:if  test="${num > 20}">  num > 20 </c:if>

		语法2:把判断的结果,存储在一个变量中.
			
			  <c:if test="${num > 20}" var="result" scope="page"/>
			
			  ${result}
	
		多条件判断:<c:choose/>标签:类似于java中switch
		
		<c:choose>
			<c:when test="${num>20}">num大于20</c:when>
			<c:when test="${num<20}">num小于20</c:when>
			<c:otherwise>num等于20</c:otherwise>
		</c:choose>
		
		在以往的时候,使用JSTL标签库的依赖的jar包:
									
											servlet-api.jar
												
											jstl.jar
											
											standard.jar
										
											el-api.jar
										
											jsp-api.jar

		开发JavaWeb依赖最少的jar:

09.foreach标签

2)循环迭代标签<c:forEach/>,类似于Java中的for-each.
		--------------------------------------------------------------------------------
		<%-- 
			需求1:1输出到10 
			1 2 3 4 5 6 7 8 9 10
		--%>
		<c:forEach var="num" begin="1" end="10" step="1">
				${num}
		</c:forEach>
		----------------------------------------------------------------------------------
		<%-- 需求2:迭代一个集合中所有的数据 --%>
		<%
				pageContext.setAttribute("list",java.util.Arrays.asList("A","B","C","D"));
		%>
		<c:forEach var="var" items="${list}">
				<br/>${var}
		</c:forEach>
		-----------------------------------------------------------------------------------
		<%-- 需求:时间格式的标签 --%>
		<%
			pageContext.setAttribute("date",new java.util.Date());
		%>
		北京时间:${date}<br/>
		<fmt:formatDate value="${date}" pattern="yyyy-MM-dd  HH:mm:ss"/>

10.Web版CRUD-商品列表界面

涉及知识点自动寻找上下文路径: ${pageContext.request.contextPath}

学会合并Servlet

servlet代码块

@WebServlet("/product")
public class ProductServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	private IProductDAO dao;

	public void init() throws ServletException {
		dao = new ProductDAOImpl();
	}

	//http://localhost/product 进入service方法,到底是保存,删除,查询
	//http://localhost/product?cmd=save //保存操作
	//http://localhost/product?cmd=delete //保存操作
	//http://localhost/product?cmd=edit //编辑操作
	//http://localhost/product //列表操作
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");//此处需要注意,一定要在代码开始的时候设置编码形式.
		String cmd = req.getParameter("cmd");
		if ("save".equals(cmd)) {
			this.saveOrUpdate(req, resp);
		} else if ("edit".equals(cmd)) {
			this.edit(req, resp);
		} else if ("delete".equals(cmd)) {
			this.delete(req, resp);
		} else {
			this.list(req, resp);
		}
	}

	//列表操作
	protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//1:接受请求参数,封装对象
		//2:调用业务方法处理请求
		List<Product> list = dao.list();
		req.setAttribute("p", list);
		//3:控制界面跳转
		req.getRequestDispatcher("/WEB-INF/views/product/product.jsp").forward(req, resp);
	}

	//编辑操作
	protected void edit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//1:接受请求参数,封装对象
		String sid = req.getParameter("id");
		if (haslength(sid)) {
			Long id = Long.valueOf(sid);
			//2:调用业务方法处理请求
			Product product = dao.get(id);
			req.setAttribute("p", product);
		}
		//3:控制界面跳转
		req.getRequestDispatcher("/WEB-INF/views/product/edit.jsp").forward(req, resp);
	}

	//删除操作
	protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Long id = Long.valueOf(req.getParameter("id"));
		dao.delete(id);
		resp.sendRedirect(req.getContextPath()+"/product");
	}

	//新增或更新操作
	protected void saveOrUpdate(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String id = req.getParameter("id");
		String productName = req.getParameter("productName");
		String brand = req.getParameter("brand");
		String supplier = req.getParameter("supplier");
		BigDecimal salePrice = new BigDecimal(req.getParameter("salePrice"));
		BigDecimal costPrice = new BigDecimal(req.getParameter("costPrice"));
		Long dir_id = Long.valueOf(req.getParameter("dir_id"));
		//Product product = new Product(productName,brand,supplier,salePrice,costPrice,cutoff,dir_id);
		Product p = new Product();
		p.setBrand(brand);
		p.setProductName(productName);
		p.setSupplier(supplier);
		p.setSalePrice(salePrice);
		p.setCostPrice(costPrice);
		p.setDir_id(dir_id);
		if (haslength(id)) {//更新
			p.setId(Long.valueOf(id));
			dao.update(p);
		} else {//新增
			dao.save(p);
		}
		//resp.sendRedirect(req.getContextPath()+"/product");
		req.getRequestDispatcher("/product").forward(req, resp);
	}

	private boolean haslength(String str) {
		return str != null && !"".equals(str.trim());
	}
}

JSP界面显示列表

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Apple inc</title>
</head>
<body>
	<a href="${pageContext.request.contextPath}/product?cmd=edit">添加商品</a>
	<table border="1" width="80%" cellpadding="0" cellspacing="0">
		<tr style="background-color: orange">
			<th>id</th>
			<th>productName</th>
			<th>brand</th>
			<th>supplier</th>
			<th>salePrice</th>
			<th>costPrice</th>
			<th>cutoff</th>
			<th>dir_id</th>
		</tr>
		<c:forEach items="${p}" var="p" varStatus="s">
			<tr style='background-color:${s.count % 2 == 0? "gray":""}'>
				<td>${p.id}</td>
				<td>${p.productName}</td>
				<td>${p.brand}</td>
				<td>${p.supplier}</td>
				<td>${p.salePrice}</td>
				<td>${p.costPrice}</td>
				<td>${p.cutoff}</td>
				<td>${p.dir_id}</td>
				<td>
					<a href="${pageContext.request.contextPath}/product?cmd=delete&id=${p.id}">删除</a>
					<a href="${pageContext.request.contextPath}/product?cmd=edit&id=${p.id}">编辑</a>
				</td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>

JSP页面编辑与添加列表

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>	
		<form action="${pageContext.request.contextPath}/product?cmd=save" method="post">
			<input type="hidden" name="id" value="${p.id}"/><br/>
			productName:<input type="text" name="productName" required value="${p.productName}"/><br/>
			brand:<input type="text" name="brand" required value="${p.brand}"/><br/>
			supplier:<input type="text" name="supplier" required value="${p.supplier}"/><br/>
			salePrice:<input type="number" name="salePrice" required value="${p.salePrice}"/><br/>
			costPrice:<input type="number" name="costPrice" required value="${p.costPrice}"/><br/>
			dir_id:<input type="number" name="dir_id" required value="${p.dir_id}"/><br/><br/>
				
				<input type="submit" value='${p == null? "保存学生信息":"修改学生信息"}'/>
		</form>
</body>
</html>

商品列表的CRUD示意图
商品列表的CRUD示意图

11.MVC思想

J2EE先后的设计思想:
	
	Model1: 模式一
		
	Model2: 模式二
	
	MVC   :  

Model1:模式一:

			在早期的时候J2EE的开发模式,是以JSP为中心.使用到技术  JSP + JavaBean

			如果是仅仅是开发一个简单的应用,完全足也.存在问题:
		
			此时JSP不仅仅需要展现界面,还得处理请求.JSP本身是不擅长处理请求的.
			
			解决方案:
					
					把处理请求的操作提取出来(Servlet).

Model2:模式二:

		
			为了解决Model1中JSP不擅长处理请求的操作,在Model2中引用了Servlet,专门用于处理请求.
			
			使用到技术: JSP + Servlet + JavaBean
			
			在Model2中,以Servlet为中心(所有请求都先发给Servlet).
		
			责任分离思想(各自做各自最擅长的事情):
			
			JSP:     界面展现.
				
			Servlet:   
						
					1:接受请求参数,封装成对象.
						
					2:调用业务方法处理请求.
						
					3:控制界面跳转
	
			JavaBean:封装功能操作,可以复用.

Model1和Model2的示意图
Model1和Model2的示意图


MVC模式最早应用于C/S框架中,在j2ee中火了.

		责任分离思想.
		
		M: Model,数据模型对象.(JavaBean)
			
		V: View,视图界面.(JSP)
			
		C: Controller控制器(Servlet)
	
		Model2属于MVC的一部分.

MVC设计思想图形版MVC设计思想图形版

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值