一: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示意图
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的示意图
MVC模式最早应用于C/S框架中,在j2ee中火了.
责任分离思想.
M: Model,数据模型对象.(JavaBean)
V: View,视图界面.(JSP)
C: Controller控制器(Servlet)
Model2属于MVC的一部分.
MVC设计思想图形版