一: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示意圖](http://img.blog.csdn.net/20180226185527921?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzQwMTYxNzA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
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的示意圖](http://img.blog.csdn.net/20180226183549944?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzQwMTYxNzA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
MVC模式最早應用於C/S框架中,在j2ee中火了.
責任分離思想.
M: Model,數據模型對象.(JavaBean)
V: View,視圖界面.(JSP)
C: Controller控制器(Servlet)
Model2屬於MVC的一部分.
![MVC設計思想圖形版](http://img.blog.csdn.net/20180226184116401?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzQwMTYxNzA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)