Sun River
Topics about Java SE, Servlet/JSP, JDBC, MultiThread, UML, Design Pattern, CSS, JavaScript, Maven, JBoss, Tomcat, ... |
1). What is a document type definition and what is its purpose in XML? Explain the difference between a well-formed and a valid XML document.
Answer: The purpose of a DTD is to define the legal building blocks of an XML document. It defines the document structure with a list of legal elements. A DTD can be declared inline in your XML document, or as an external reference. Two definitions:
?? -).A well-formed file is one that obeys the general XML rules for tags: tags must be properly nested, opening and closing tags must be balanced, and empty tags must end with '/>'
.
?? -). A valid file is not only well-formed, but it must also conform to a publicly available DTD that specifies which tags it uses, what attributes those tags can contain, and which tags can occur inside which other tags, among other properties.
2). External DTD:
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
3). Minimal but Complete XSLT? Stylesheet
<?xml version="1.0"?>
?? <
xsl:stylesheet
version="1.0"
??????????? xmlns:xsl="http://www.w3.org/1999/
XSL/Transform">
<
/xsl:stylesheet
>
4). Using XSLT, how would you extract a specfic attribute from an element in an XML document?
Ans: Extract attributes from XML data
?? <xsl:template match="element-name">
???? Attribute Value:
??????? <xsl:value-of select="@attribute" />
???????? <xsl:apply-templates/>
??? </xsl:template>
5). Templates--Controls which output is created from which input
--"
xsl:template
element form
--"
match
attribute contains an Xpath expression (Xpath expression identifies input node set it matches)
--"
For each node in the node set, the
template contents
(things between xsl:template tags) are instantiated and inserted into the output tree.
6). Attributes
In the DTD, XML element attributes are declared with an ATTLIST declaration. An attribute declaration has the following syntax:
<!ATTLIST element-name attribute-name attribute-type default-value> |
The attribute-type can have the following values:
Value | Explanation |
---|---|
CDATA | The value is character data |
(eval|eval|..) | The value must be an enumerated value |
ID | The value is an unique id |
IDREF | The value is the id of another element |
IDREFS | The value is a list of other ids |
NMTOKEN | The value is a valid XML name |
NMTOKENS | The value is a list of valid XML names |
ENTITY | The value is an entity |
ENTITIES | The value is a list of entities |
NOTATION | The value is a name of a notation |
xml: | The value is predefined |
The attribute-default-value can have the following values:
Value | Explanation |
---|---|
#DEFAULT value | The attribute has a default value |
#REQUIRED | The attribute value must be included in the element |
#IMPLIED | The attribute does not have to be included |
#FIXED value | The attribute value is fixed |
DTD example: <!ELEMENT square EMPTY> <!ATTLIST square width CDATA "0"> XML example: <square width="100"></square> |
Syntax: <!ATTLIST element-name attribute-name CDATA "default-value"> DTD example: <!ATTLIST payment type CDATA "check"> XML example: <payment type="check"> |
Syntax: <!ATTLIST element-name attribute-name attribute-type #IMPLIED> DTD example: <!ATTLIST contact fax CDATA #IMPLIED> XML example: <contact fax="555-667788"> |
Syntax: <!ATTLIST element-name attribute_name attribute-type #REQUIRED> DTD example: <!ATTLIST person number CDATA #REQUIRED> XML example: <person number="5677"> |
Syntax: <!ATTLIST element-name attribute-name attribute-type #FIXED "value"> DTD example: <!ATTLIST sender company CDATA #FIXED "Microsoft"> XML example: <sender company="Microsoft"> |
Syntax: <!ATTLIST element-name attribute-name (eval|eval|..) default-value> DTD example: <!ATTLIST payment type (check|cash) "cash"> XML example: <payment type="check"> or <payment type="cash"> |
Set J2EE server environment variables—Environment variables must be set for running a J2EE server environment and vary per vendor implementation and operating-system platform.
Configure J2EE server properties—Configuration properties for most J2EE server implementations can be set to suit your particular network and operating environment.
Compile J2EE EJB application code—All J2EE EJB implementation, home, remote, and dependent utility code must be compiled using a standard Java compiler.
Create a J2EE EJB application deployment descriptor—An XML-based deployment descriptor is created according to the EJB application DTD. Some vendor products can create this file for you from a GUI-based configuration tool.
Create vendor-specific deployment descriptors—Because no standard means exists to bind J2EE standard EJB reference names to a J2EE server's JNDI-based naming service, a vendor-specific deployment descriptor mechanism is required to perform this mapping. This deployment descriptor must map EJB reference names used by J2EE components to the actual JNDI names associated with EJB home interfaces. Other vendor-specific properties may also be set for customizing both session and entity beans. Vendors may provide a GUI-based means to configure these files.
Package J2EE EJB application code—The EJB deployment descriptors, all compiled J2EE EJB implementation classes, all compiled J2EE EJB implementation interfaces, and all other compiled classes dependent on your EJBs need to be packaged into an EJB JAR file with a .jar extension. J2EE-based products might supply command-line or GUI-based utilities for this purpose.
Start the J2EE server—The J2EE-compliant server must generally be started at this stage. The exact mechanism for starting a server is often vendor-dependent but can be as simple as invoking a single startup command from the command line.
Create a J2EE application deployment descriptor—A J2EE application deployment descriptor must be created to collect one or more Web, EJB, and application client modules into a cohesive J2EE application. Many products will create this file for you automatically or via a GUI-based configuration tool.
Package J2EE application code—The application and JNDI mapping deployment descriptor, Web applications, EJB applications, and application clients need to be packaged into an enterprise archive (EAR) file with an extension of .ear. Many products also create this archive for you automatically or via GUI-based development tools.
Deploy the J2EE enterprise application code—Finally, the integrated J2EE application is deployed to the J2EE server environment for access by enterprise application clients. This step is also often automated via GUI tools. http://e-docs.bea.com/wls/docs61/webapp/webappdeployment.html
???
??? AOP
作為
Spring
這個輕量級的容器中很重要的一部分,得到越來越多的關注,
Spring
的
Transaction
就是用
AOP
來管理的,今天就通過簡單的例子來看看
Spring
中的
AOP
的基本使用方法。
?
?
首先確定將要
Proxy
的目標,在
Spring
中默認采用
JDK
中的
dynamic proxy
,它只能夠實現接口的代理,如果想對類進行代理的話,需要采用
CGLIB
的
proxy
。顯然,選擇
“
編程到接口
”
是更明智的做法。
?
下面是將要代理的接口:
public interface FooInterface {
??? public void printFoo();
??? public void dummyFoo();
}
以及其一個簡單的實現:
public class FooImpl implements FooInterface {
??? public void printFoo() {
??????? System.out.println("In FooImpl.printFoo");
??? }
??? public void dummyFoo() {
??????? System.out.println("In FooImpl.dummyFoo");
??? }
}
?
接下來創建一個
Advice
,在
Spring
中支持
Around,Before,After returning
和
Throws
四種
Advice
,這里就以簡單的
Before Advice
舉例:
?
public class PrintBeforeAdvice implements MethodBeforeAdvice {
??? public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
??????? System.out.println("In PrintBeforeAdvice");
??? }
}
?
有了自己的
business interface
和
advice
,剩下的就是如何去裝配它們了,首先利用
ProxyFactory
以編程方式實現,如下:
?
public class AopTestMain {
??? public static void main(String[] args) {
??????? FooImpl fooImpl = new FooImpl();
??????? PrintBeforeAdvice myAdvice = new PrintBeforeAdvice();
?????
?????? ?ProxyFactory factory = new ProxyFactory(fooImpl);
??????? factory.addBeforeAdvice(myAdvice);
??????? FooInterface myInterface = (FooInterface)factory.getProxy();
??????? myInterface.printFoo();
??????? myInterface.dummyFoo();
??? }
}
?
?
現在執行程序,神奇的結果就出現了:
?
? In PrintBeforeAdvice
? In FooImpl.printFoo
? In PrintBeforeAdvice
? In FooImpl.dummyFoo
?
??
雖然這樣能體會到
Spring
中
AOP
的用法,但這決不是值得推薦的方法,既然使用了
Spring
,在
ApplicationContext
中裝配所需要
的
bean
才是最佳策略,實現上面的功能只需要寫個簡單的
applicationContext
就可以了,如下:
?
? <?xml version="1.0" encoding="UTF-8"?>
? <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
??? "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
??? <description>The aop application context</description>
??? <bean id="fooTarget" class="FooImpl"/>
??? <bean id="myAdvice" class="PrintBeforeAdvice"/>
?? ?<bean id="foo" class="org.springframework.aop.framework.ProxyFactoryBean">
???? <property name="proxyInterfaces">
?????? <value>FooInterface</value>
???? </property>
?????<property name="target">
?????? <ref local="fooTarget"/>
???? </property>
???? <property name="interceptorNames">
?????? <list>
???????? <value>myAdvice</value>
?????? </list>
???? </property>
??? </bean>
</beans>
?
??
當然,
main
中的代碼也要進行相應的修改:
????
public static void main(String[] args) {
??? ClassPathXmlApplicationContext context = new?
?????????????ClassPathXmlApplicationContext("applicationContext.xml");
??? FooInterface foo = (FooInterface)context.getBean("foo");
??? foo.printFoo();
??? foo.dummyFoo();
}
?
??
現在運行一下,結果將和上面的運行結果完全一樣,這樣是不是更優雅?當需要更改實現時,只需要修改配置文件就可以了,程序中的代碼不需任何改動。
?
??
但是,這時候會發現被
proxy
的
object
中的所有方法調用時都將運行
advice
中的
before
,這顯然不能滿足絕大多數情況下的需要,此時,只
需借用
Advisor
就可以了,當然要在
Advisor
中利用
pattern
設置好哪些方法需要
advice
,更改
applicationContext
如下:
?
? <?xml version="1.0" encoding="UTF-8"?>
? <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
??? "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
??? <description>The springeva application context</description>
?? ?<bean id="fooTarget" class="FooImpl"/>
??? <bean id="printBeforeAdvice" class="PrintBeforeAdvice"/>
??? <bean id="myAdvisor"
????????? class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
????? <property name="advice">
??????? <ref local="printBeforeAdvice"/>
????? </property>
????? <property name="pattern">
??????? <value>.*print.*</value>
????? </property>
??? </bean>
??? <bean id="foo" class="org.springframework.aop.framework.ProxyFactoryBean">
????? <property name="proxyInterfaces">
????????<value>FooInterface</value>
????? </property>
????? <property name="target">
??????? <ref local="fooTarget"/>
????? </property>
????? <property name="interceptorNames">
??????? <list>
????????? <value>myAdvisor</value>
??????? </list>
??????</property>
??? </bean>
</beans>
?
???
主程序不需進行任何修改,運行結果已經變樣了
?? In PrintBeforeAdvice
??? In FooImpl.printFoo
??? In FooImpl.dummyFoo
?
??
至此,應該已經理解了
Spring
中
AOP
的使用方法,當然
Spring
中
AOP
最重要的應用是
Transaction Manager
,舉個這方面的
applicationContext
例子看看:
?
? <?xml version="1.0" encoding="UTF-8"?>
? <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "spring-beans.dtd">
<beans>
??? <bean id="propertyConfigurer"???
???????? class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
????? <property name="location">
??????? <value>/WEB-INF/jdbc.properties</value>
??????</property>
?? ?</bean>
??? <bean id="dataSource"
????????? class="org.springframework.jdbc.datasource.DriverManagerDataSource">
????? <property name="driverClassName">
??????? <value>${jdbc.driverClassName}</value>
????? </property>
??????<property name="url">
??????? <value>${jdbc.url}</value>
????? </property>
????? <property name="username">
??????? <value>${jdbc.username}</value>
????? </property>
????? <property name="password">
??????? <value>${jdbc.password}</value>
????? </property>
??? </bean>
?? ?<bean id="sessionFactory"
????????? class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
????? <property name="dataSource">
??????? <ref local="dataSource"/>
????? </property>
????? <property name="mappingResources">
??????? <value>smartmenu.hbm.xml</value>
????? </property>
????? <property name="hibernateProperties">
??????? <props>
????????? <prop key="hibernate.dialect">${hibernate.dialect}</prop>
??????? </props>
????? </property>
??? </bean>
?
??? <bean id="transactionManager"???????
????????? class="org.springframework.orm.hibernate.HibernateTransactionManager">
????? <property name="sessionFactory">
??????? <ref local="sessionFactory"/>
????? </property>
??? </bean>
??? <bean id="smartmenuTarget" class="SmartMenuHibernate">
????? <property name="sessionFactory">
??????? <ref local="sessionFactory"/>
????? </property>
??? </bean>
?? ?<bean id="smartMenu"
??????? class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
????? <property name="transactionManager">
??????? <ref local="transactionManager"/>
????? </property>
????? <property name="target">
??????? <ref local="smartmenuTarget"/>
????? </property>
????? <property name="transactionAttributes">
??????? <props>
????????? <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
????????? <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
??????? </props>
????? </property>
??? </bean>
? </beans>
?
?
要想徹底理解
Spring
的
AOP
,最好還是多看看源碼,開源就是好啊!
J2EE
五層邏輯模型和常見
Framework
?
?
???????????????????? ?————————————————
????????????????????? |?????????????????????????
客戶端層
????????????????????|???????
用戶交互,
UI
實現
??????????????????????| Browser,WirelessDevice,WebService |??? Http, Soap
協議
(SOP
體系
)
????????????????????? ————————————————
?
??????????????????????————————————————
????????????????????? |?????????????????????????? ?
表現層
????????????????????? |??
集中登錄,會話管理
??????????????????????|?Struts,Jsf,Webwork,Tapstry,?Velocity |
內容創建,格式,傳送
????????????????????? ————————————————
?
???????????????????????————————————————
?????????????????????? |??????????????????????
業務服務層
???????????? ?????? |??
業務邏輯
,
事務
,
數據
,
服務
???????????????????????| SessionEJB
,
Spring
,
Jdoframework) |?SessionEjb
,
POJO Service
??????????????????????? ————————————————
?
???????????????????????————————————————
???????????????????????|???????????????????????????
集中層
?????????????????????? |?
資源適配器,遺留
/
外部系統
?
???????????????????????|Jms,Jdbc,Connnector,External Service? |????? ?
規則引擎,工作流
???????????????????????————————————————
???????????????????????(
持久化
EntityBean,Hibernate,iBatis,Jdo,Dao,TopLink etc.)??????
?
????????????????????????————————————————
????????????????????????|??????????????????????????
資源層
??????????????????????????? |
資源,數據庫,外部服務
????????????????????????| DataBase,Resource,External Service???| (
大型主機,
B2B
集中系統
)
????????????????????????————————————————
?
當然一個常見典型的
J2EE
系統可能是這樣的
?
客戶端
——
表現層
——
業務層
?——
持久層
——
數據庫
??
FireFox + Velocity + Struts + Spring + Hibernate + MySql + Tomcat + Eclipse
我比較習慣用開源產品。強烈支持開源
!! *.*
???????????????????????????????????????????????????????????
作為一個程序員,常常打交道的是中間層
(
表現層,業務層,集成層
)
。
每個層常用的技術簡單的介紹如下:
表現層
(Present Tier)
Intercepting Filter ——
用于對請求的預處理和后處理
?
???
攔截過濾器攔截輸入的請求和輸出的響應,并加入了一個過濾器。
Filter
可以通過配置加入和取消
(
象在
web.xml
中加入
ServletFilter)
,這樣多個過濾器還可以不沖突地組合使用。當預處理以及
/
或者
(filter
雖然后
response
參數,但有時候
filter
不做處理
)
后處理完成后,這組過濾器種的最后一個把控制器交給原來的目標對象。對于
request
來說,這個目標對象通常是前端控制器,但也可能是一個視圖。在
Struts
中,
Action
的執行方法中參數由
request, response, actionMapping,actionForm
等等組成。而在
Webwork
中,
Action
不用去依賴于任何
Web
容器,不用和那些
JavaServlet
復雜的請求(
Request
)、響應
(Response)
關聯在一起。對請求(
Request
)的參數
(Param)
,可以使用攔截器框架自動調用一些
get()
和
set()
方法設置到對應的
Action
的字段中。所以
Action
的
excute()
方法沒有任何參數,也不存在
FormBean
。正是這種攔截器,使得
Action
變得非常簡單,
Action
不用繼承
servlet
,不依賴
servlet
容器,實現了請求響應與
Action
之間的解耦,而且可以很方便的在
action
中不依賴
web
容器進行單元測試。
?
Front Controller ——
集中控制請求處理
?
???
前端控制器是一個容器,用來裝載表現層的共同處理邏輯
(
如果不采用這個控制器,邏輯代碼就會錯誤的放在視圖里
)
??刂破髫撠熖幚碚埱螅M行內容的獲取,安全性,視圖管理,導航等操作,并委派一個分配器組件分派視圖。
?
Application Controller ——
實現操作和視圖管理的集中化,模塊化
?
???
應用控制器集中了控制,數據獲取,視圖和命令處理的調用。前端控制器為輸入的請求提供了一個集中的訪問點和控制器,而應用控制器則負責找出并調用命令,并且還要找出并分派視圖。比如
Struts
中的
ActionServlet,Webwork
種的
ServletDispatcher
等。
1). Steps for Building a JMS Sender Application
1.Get ConnectionFactory and Destination object (Topic or Queue) through JNDI?????????
// Get JNDI InitialContext object
Context jndiContext = new InitialContext();
// Locate ConnectionFactory object via JNDI
TopicConnectionFactory factory =
????? (TopicConnectionFactory) jndiContext.lookup("MyTopicConnectionFactory");
// Locate Destination object (Topic or Queue) through JNDI
Topic weatherTopic = (Topic) jndiContext.lookup("WeatherData");
3.Create a Session to send/receive messages
?????????// Create a Session from Connection object.
????????????// 1st parameter controls transaction
????????????// 2nd parameter specifies acknowledgment type
?????????TopicSession session =
????????????topicConnection.createTopicSession (false, Session.CLIENT_ACKNOWLEDGE);
4.Create a MessageProducer (TopicPublisher or QueueSender)
??????????????????????????????????????????// Create MessageProducer from Session object
??????????????????????????????// TopicPublisher for Pub/Sub
??????????????????????????????// QueueSender for Point-to-Point
??????????????????????????????TopicPublisher publisher =session.createPublisher(weatherTopic);
5.Start Connection
????????????????????????????????????????????????// Until Connection gets started, message flow
????????????????????????????????????// is inhibited: Connection must be started before
????????????????????????????????????// messages will be transmitted.
????????????????????????????????????topicConnection.start();
6.Send (publish) messages
????????????????????????????????????// Create a Message
?????????????????????????????????????TextMessage message =session.createMessage();
????????????????????????????????????message.setText("text:35 degrees");
????????????????????????????????????// Publish the message
????????????????????????????????????publisher.publish(message);
7.Close Session and Connection
2). Steps for Building a JMS Receiver Application (non-blocking mode)
1.Get ConnectionFactory and Destination object
(Topic or Queue) through JNDI
2.Create a Connection
3.Create a Session to send/receive messages
4.Create a MessageConsumer (TopicSubscriber or QueueReceiver)
????????????// Create Subscriber from Session object
????????????TopicSubscriber subscriber =session.createSubscriber(weatherTopic);
5.Register MessageListener for non-blocking mode
?????????WeatherListener myListener= new WeatherListener();
?????????// Register MessageListener with TopicSubscriber object
?????????subscriber.setMessageListener(myListener);
6.Start Connection
7.Close Session and Connection
3). Steps for Building a JMS Receiver Application for blocking mode)
1.Get ConnectionFactory and Destination object (Topic or Queue) through JNDI
2.Create a Connection
3.Create a Session to send/receive messages
4.
Create a MessageConsumer5.Start Connection
6.
Receive message7.Close Session and Connection
摘要: 閱讀全文context - the context for the JSP page's servlet and any Web components contained in the same application.
session - the session object for the client.
request - the request triggering the execution of the JSP page.
pageScope - a java.util.Map that maps page-scoped attribute names to their values.
requestScope - a java.util.Map that maps request-scoped attribute names to their values.
sessionScope - a java.util.Map that maps session-scoped attribute names to their values.
applicationScope - a java.util.Map that maps application-scoped attribute names to their values.
param - a java.util.Map that maps parameter names to a single String parameter value (obtained by calling ServletRequest.getParameter(String name)).
paramValues - a java.util.Map that maps parameter names to a String[] of all values for that parameter (obtained by calling ServletRequest.getParameterValues(String name)).
header - a java.util.Map that maps header names to a single String header value (obtained by calling HttpServletRequest.getHeader(String name)).
headerValues - a java.util.Map that maps header names to a String[] of all values for that header.
cookie - a java.util.Map that maps cookie names to a single Cookie object. Cookies are retrieved according to the semantics of HttpServletRequest.getCookies(). If the same name is shared by multiple cookies, an implementation must use the FIRST one encountered in the array of Cookie objects returned by the getCookies() method. However, users of the cookie implicit object must be aware that the ordering of cookies is currently unspecified in the servlet specification.
initParam - a java.util.Map that maps context initialization parameter names to their String parameter value (obtained by calling ServletContext.getInitParameter(String name)).
Examples:
The request's URI (obtained from HttpServletRequest):
${pageContext.request.requestURI}
The value of the numberOfItems property of the session-scoped attribute named cart:
${sessionScope.cart.numberOfItems}
The context path:
${pageContext.request.contextPath}
The session-scoped attribute named 'profile' (null if not found):
${sessionScope.profile}
The String value of the productId parameter, or null if not found:
${param.productId}
The value of the productId request parameter:
${param["productId"]}
The String[] containing all values of the productId parameter, or null if not found:
${paramValues.productId}
A collection's members can be accessed using square brackets as shown by retrieval of the userName parameter from the param object. Members of an array or List can be accessed if the value in square brackets can be coerced to an int.
<html> <head><title>Customer Profile for ${param["userName"]}</title></head> <body> ... </body> </html>Maps can be accessed using the dot operator OR square brackets. For example, ${param.userName} is EQUIVALENT to ${param["userName"]}.
The host HTTP attribute:
${header["host"]}
Here is an example of accessing a page-scoped object that is called pageColor:
<body bgcolor="${pageScope.pageColor}">it is equivalent to:
<body bgcolor="${pageScope['pageColor']}">
<form-login-config>
tag in the <login-config>
subelement of the generated web.xml
file.