Use STRUTS + spring + hibernate to assemble your web application architecture

Source: Internet
Author: User
Tags create domain
In fact, even if you use Java to build a web application that is not very cumbersome, it is not easy. There are many things to consider at the beginning of the architecture. From a high point of view, there are many questions for developers: How to Establish user interfaces? Where can I process the business logic? How to persist data. In this three-layer architecture, each layer should be carefully considered. What technologies should each layer use? What kind of design can be loosely coupled and flexibly changed? How to replace a layer without affecting the overall architecture? How does an application perform various levels of business processing (such as transaction processing )?

To build a web application, you need to understand many problems. Fortunately, many developers have already encountered such problems and established a framework to deal with such problems. A good framework has the following aspects: reduce the burden on developers to deal with complex problems ("Do not reinvent the wheel"); there are good internal extensions; and there is a strong user group that supports it. A good architecture generally deals with a specific type of problem and can do one thing well ). However, there are several layers in your program that may need to use a specific framework, the completed UI (User Interface) it does not mean that you can also combine your business logic and persistent logic into your UI. For example, you shouldn't write JDBC code in a controller as your business logic. This is not what the Controller should provide. A ui controller should be delegated to other lightweight components outside the UI scope. A good framework should guide the distribution of code. More importantly, the Framework frees developers from coding so that they can concentrate on the logic of the application (which is important to customers ).

This article will discuss how to combine several well-known frameworks to make your applications relaxed and coupled.
How can we build your architecture and make your application layers consistent .? How can we integrate the framework so that each layer can interact with each other in a loose way without considering the technical details of the lower layer? This is a challenge for us. Here we will discuss an Integrated Framework Strategy (using three popular open-source frameworks): Presentation layer we use struts; business layer we use spring; persistence layer uses hibernate. You can also use other frameworks to achieve the same effect. See Figure 1 (Framework combination)

Application hierarchy

Most Web applications can be divided into at least four layers in terms of responsibilities. The four layers are presentation, persistence, business, and domain model ). Each layer should have a clear responsibility in the processing program, instead of mixing functions with other layers, and each layer should be separated from other layers, however, a communication interface should be provided between them. Let's start with introducing various layers and discuss what these layers should provide and what they should not.

The presentation layer)

Generally, the end of a typical web application is the presentation layer. Many Java developers also understand what Struts provides. Such as business logic is packaged into Org. Apache. Struts. action. Therefore, we are in favor of using a framework such as struts.

Struts is responsible for the following:

* Manage user requests and respond accordingly.

* A controller is provided to delegate calls to business logic and other upper-layer processes.

* Handle the exception and send it to the struts action.

* Provide a model for display.

* UI verification.

The following terms should not appear frequently in the encoding of the struts display layer. They are independent of the display layer.

* Directly communicates with databases, such as JDBC calls.

* Business logic associated with your application and verification.

* Transaction management.

Introducing the code in the presentation layer will bring about high coupling and troublesome maintenance.

The Persistence Layer)

Another end of a typical web application is the persistent layer. This is usually the easiest place for programs to get out of control. Developers always underestimate the challenge of building their own persistent frameworks. The continuity layer inside the system not only requires a lot of debugging time, but also often lacks functions to make it difficult to control. This is a common problem of the persistence layer. Fortunately, several open-source ORM frameworks can solve such problems well. Especially hibernate. Hibernate provides the or persistence mechanism and query service for Java. It also provides a learning bridge for Java developers who are familiar with SQL and JDBC APIs. It is easy to learn. Hibernate's persistent objects are based on pojo and Java collections. In addition, using hibernate does not prevent you from using the IDE.

Please refer to the following entries, which you need to know in the persistent layer encoding.

* Statement used to query the related information of an object. Hibernate uses an OO Query Language (hql) or regular expression API to complete the query. Hql is very similar to SQL-it only replaces the table and columns in SQL With the object and its fields. You need to learn some new hql languages, which are easy to understand and well documented. Hql is a natural language for object query. It can be learned at a very low cost.

* How to store, update, and delete database records.

* Advanced ORM frameworks such as Hibernate support most mainstream databases and support parent/child relationships, transaction processing, inheritance, and polymorphism.

The Business Layer)

The middle part of a typical web application is the business layer or service layer. From the coding perspective, this layer is the most easily overlooked layer. However, we often see the code processed by these services around the ui or persistence layer. This is actually incorrect because it causes close coupling of program code. As a result, the code is difficult to maintain over time. Fortunately, there are several frameworks for this problem. The two most popular frameworks are spring and picocontainer. These are also called microcontainers, which can be used together with objects. Both of these frameworks focus on the simple concept of 'dependency injection (and we know that 'inversion of control' inversion of control = IOC. This article will focus on Spring injection (Note: using a setter Method for given parameters to construct beans, different from factory). Spring also provides setter injection (type2 ), constructor injection (type3) and other methods for us to choose. Spring objects that involve the business logic and Dao involved in the program-such as transaction management handler (thing management control), object factoris (Object factory), service objects (service component) -- All are configured and linked through XML.

We will give an example to illustrate how spring uses these concepts.

The business layer is responsible for the following:

* Process application business logic and business Validation

* Manage things

* Interfaces that allow interaction with other layers

* Manage the dependencies of objects at the business layer.

* A flexible mechanism is added between the display layer and the persistent layer so that they are not directly linked together.

* Business services are obtained by revealing the context between the display layer and the business layer.

* Management Program Execution (from the business layer to the persistent layer ).

The domain model layer)
Since we are committed to a web application that is not very complex, we need an object set to move it between different layers. The domain Module layer consists of business objects in actual needs, such as orderlineitem and product. On this layer, developers do not need to care about those dtos, but only focus on domain objects. For example, Hibernate allows you to store information in the database into the object (domain objects), so that you can display the data to the UI Layer when the connection is disconnected. The objects can also be returned to the persistence layer to be updated in the database. Moreover, you do not need to convert an object to dtos (this may be like it is lost during transmission between different layers). This model allows Java developers to naturally use Oo, no additional encoding is required.

A simple example

Since we have understood these components globally. Now let's get started. We still use struts, spring, and hibernate. The three frameworks have been described enough, so we will not repeat them here. This article provides an example of how to use these three frameworks for integrated development and shows you how a request runs through various layers. (From adding a user order to the database for display, and then updating and deleting ).

You can download the original program code (download) from here)

Since each layer interacts with each other, we will first create domain objects. First, we need to determine in these objects what are persistent, which are provided to business logic, and those are the design of the display interface. Next, we will configure our persistence layer and define the hibernate or mappings. Then define business objects. With these components, we will use spring to connect these components. Finally, we provide spring with a persistent layer from which we can know how it communicates with the business service layer, and how it handles exceptions thrown by other layers ..

Domain object Layer)

This layer is the starting point of encoding, and our encoding starts from this layer. In this example, order and orderitem are in one-to-one relationship. The following are two objects of the domain object Layer:

· Com. Meagle. Bo. Order. Java: contains the summary of an order.

· Com. Meagle. Bo. orderlineitem. Java: contains the Order details.

Think about how to name your package, which reflects how you layered it. For example, domain objects may be packaged in COM. Meagle. Bo in the program. For more details, it will be packaged under the subdirectory com. Meagle. Bo. Business logic should start packaging from Com. Meagle. serice, And the DaO object should be located in COM. Meagle. Service. Dao. hibernate. The expression classes of forms and actions should be placed in the com. Meagle. Action and COM. Meagle. Forms packages respectively. Accurate package naming makes your classes well segmented and easy to maintain. When you add a new classes, the program structure can be kept up and down.

Persistence Layer Configuration)

Several steps are required to establish the persistence layer of hibernate. The first step is to make Bo persistent. Since hibernate works through pojo, the order and orderlineitem objects need to add the getter and setter methods to all fileds. Hibernate maps (OR) objects through XML files. The following two XML files map order and orderitem objects respectively. (Here is an XDoclet tool that can automatically generate your XML injection file)

-Order. HBM. xml
-Orderlineitem. HBM. xml

You can find these XML files in the webcontent/WEB-INF/classes/COM/Meagle/bo directory. Hibernate's [urlhttp: // Protocol [/url] is used to tell the program which database should communicate with, which connection pool should be used or datasource should be used, and which persistent objects should be loaded. The session interface is used to perform operations such as selecting, saving, delete, and updating. The following describes how to set sessionfactory and session.

Business Layer Configuration)

Now that we have domain objects, we need to use business service objects to execute the logic of the program, call the persistent layer, obtain the requests of the UI Layer, and process transactions, and control exceptions. To connect these connections and make them easy to manage, we will use the Aspect-Oriented springframework. Spring provides the inversion of Control 0 = IOC and setter dependency injection methods to connect objects with XML files. IOC is a simple concept (it allows an object to be created by other objects on the upper layer). In this way, IOC releases your object from the creation and reduces the coupling.

Here is an example of creating an object without IOC, which has a high Coupling Degree.

Figure 2. No IOC. A is used to create B and C

Here is an example of using IOC. This method allows an object to be created at the upper level and enter another object, so it can be directly executed.

Figure 3. IOC is used for the object. A contains the setter method that accepts B and C, which also achieves the goal of creating B and C by.

Building our business service objects)

The setter method in Business Object accepts interfaces, so that we can define the object implementation loose and inject it. In our case, we will use a business service object to receive a Dao and use it to control the persistence of domain objects. Since Hibernate is used in this example, we can easily implement it using other persistent frameworks and notify spring that a New Dao can be used.

In interface-oriented programming, you will understand how the "injection dependency" mode is loosely coupled with your business logic and persistence mechanism :).

The following is a DaO code snippet of the business service object interface:

Code:
Public interface iorderservice {

Public Abstract Order saveneworder (order)

Throws orderexception,

Orderminimumamountexception;

Public abstract list findorderbyuser (

String user)

Throws orderexception;

Public Abstract Order findorderbyid (int id)

Throws orderexception;

Public abstract void setorderdao (

Iorderdao orderdao );

}

Note that there is a setorderdao () in this code, which is a DaO object setting method (syringe ). However, there is no getorderdao method here. This is not necessary because you will not access this orderdao externally. This Dao objecte will be called to communicate with our persistence layer. We will use spring to combine Dao object and business service object. Because we are interface-oriented, we do not need to closely couple the implementation classes.

Next, we start coding the DAO implementation class. Since spring already supports hibernate, this example inherits the hibernatedaosupport class directly. This class is very useful. We can refer to hibernatetemplate (which is mainly used for hibernatedaosupport: for details, refer to the srping API ). The Dao interface code is as follows:

Code:
Public interface iorderdao {
Public Abstract Order findorderbyid (
Final int ID );

Public abstract list findordersplacebyuser (
Final string placedby );
Public Abstract Order saveorder (
Final Order order );
}

We still need to assemble many associated objects for our persistence layer, including hibernatesessionfactory and transactionmanager. Spring provides a hibernatetransactionmanager. He binds a hibernate session with a thread to support transactions (see threadlocal ).

The configuration of hibernatesessionfactory and hibernatetransactionmanager is as follows:

Code:
<Bean id = "mysessionfactory"
Class = "org. springframework. Orm. hibernate.
Localsessionfactorybean ">
<Property name = "mappingresources">
<List>
<Value>
COM/Meagle/bo/order. HBM. xml
</Value>
<Value>
COM/Meagle/bo/orderlineitem. HBM. xml
</Value>
</List>
</Property>
<Property name = "hibernateproperties">
<Props>
<Prop key = "hibernate. dialect">
Net. SF. hibernate. dialect. mysqldialect
</Prop>
<Prop key = "hibernate. show_ SQL">
False
</Prop>
<Prop key = "hibernate. proxool. xml">
C:/mywebapps/../WEB-INF/proxool. xml
</Prop>
<Prop key = "hibernate. proxool. pool_alias">
Spring
</Prop>
</Props>
</Property>
</Bean>

<! -- Transaction Manager for a single hibernate
Sessionfactory (alternative to JTA) -->
<Bean id = "mytransactionmanager"
Class = "org.
Springframework.
Orm.
Hibernate.
Hibernatetransactionmanager ">
<Property name = "sessionfactory">
<Ref local = "mysessionfactory"/>
</Property>
</Bean>

We can see that each object can be referenced by the <bean> label in the spring configuration information. Here, mysessionfactory references hibernatesessionfactory, while mytransactionmanager references hibernatetransactionmanage. Note that mytransactionmanger bean in the Code has a sessionfactory attribute. Hibernatetransactionmanager has a sessionfactory setter and getter method, which is used to implement dependency injection when spring starts. Reference mysessionfactory in the sessionfactory property. These two objects are assembled after spring container initialization. This combination frees you from Singleton objects and factories and reduces the code maintenance cost. The two attributes of mysessionfactory are used to inject mappingresources and hibernatepropertes. Generally, if you use hibernate outside of spring, such settings should be placed in hibernate. cfg. xml. In any case, Spring provides a convenient way-the hibernate configuration is incorporated into the internal configuration of spring. For more information, see spring API.

Now that we have assembled and configured service beans, We need to assemble the business service objects and Dao and configure these objects in a transaction manager.

Configuration Information in Spring:

Code:
<! -- Order service -->
<Bean id = "orderservice"
Class = "org.
Springframework.
Transaction.
Interceptor.
Transactionproxyfactorybean ">
<Property name = "transactionmanager">
<Ref local = "mytransactionmanager"/>
</Property>
<Property name = "target">
<Ref local = "ordertarget"/>
</Property>
<Property name = "transactionattributes">
<Props>
<Prop key = "find *">
Propagation_required, readonly,-orderexception
</Prop>
<Prop key = "Save *">
Propagation_required,-orderexception
</Prop>
</Props>
</Property>
</Bean>

<! -- Order target primary business object:
Hibernate implementation -->
<Bean id = "ordertarget"
Class = "com.
Meagle.
Service.
Spring.
Orderservicespringimpl ">
<Property name = "orderdao">
<Ref local = "orderdao"/>
</Property>
</Bean>

<! -- Order Dao object -->
<Bean id = "orderdao"
Class = "com.
Meagle.
Service.
Dao.
Hibernate.
Orderhibernatedao ">
<Property name = "sessionfactory">
<Ref local = "mysessionfactory"/>
</Property>
</Bean>

Figure 4 is an outline of Object Construction. It can be seen that every object is associated with spring and can be injected to other objects through spring. Compare it with the spring configuration file and observe the relationship between them.

Figure 4. Spring builds beans together based on the configuration file.

In this example, a transactionproxyfactorybean is used to define a settransactionmanager (). This object is very useful, and it can easily process the items you declare and the service object. You can use the transactionattributes attribute to define how to handle it. For more information, see transactionattributeeditor.

Transactionproxyfactorybean also has a setter. This will be referenced by our business service object (ordertarget). ordertarget defines the business service layer and has an attribute that is referenced by setorderdao. This attribute

Spring and bean have another note: bean can be created in two ways. These are all defined in sington and propotype. The default method is Singleton, which means the shared instance will be bound. The original model allows new instances when bean is used by spring. When each user needs to get the copy of their own bean, you should only use the prototype mode. (For more information, see Singleton mode and prototype mode in design mode)

Provides a service locator (providing a service locator)
Now that we have matched our serices and Dao. We need to display our service to other layers. This is usually encoded in the struts or swing layer. A simple method is to use the service locator to return to spring context. Of course, you can directly call the bean in spring.

The following is an example of a service positioner in struts _ 1.

Code:
Public abstract class baseaction extends action {

Private iorderservice orderservice;

Public void setservlet (actionservlet
Actionservlet ){
Super. setservlet (actionservlet );
Servletcontext =
Actionservlet. getservletcontext ();

Webapplicationcontext WAC =
Webapplicationcontextutils.
Getrequiredwebapplicationcontext (
Servletcontext );

This. orderservice = (iorderservice)
WAC. getbean ("orderservice ");
}

Protected iorderservice getorderservice (){
Return orderservice;
}
}

UI Layer Configuration)

In this example, the UI Layer uses the Struts framework. Here we will describe what is related to struts when layering the program. Let's start with the action configuration information in a Struts-config.xml file.

Code:
A struts-config.xml file.

<Action Path = "/saveneworder"
Type = "com. Meagle. Action. saveorderaction"
Name = "orderform"
Scope = "request"
Validate = "true"
Input = "/neworder. jsp">
<Display-Name> Save New Order </display-Name>
<Exception key = "error. Order. Save"
Path = "/neworder. jsp"
Scope = "request"
Type = "com. Meagle. Exception. orderexception"/>
<Exception key = "error. Order. Not. Enough. Money"
Path = "/neworder. jsp"
Scope = "request"
Type = "com.
Meagle.
Exception.
Orderminimumamountexception "/>
<Forward name = "success" Path = "/vieworder. jsp"/>
<Forward name = "failure" Path = "/neworder. jsp"/>
</Action>

The saveneworder action is used to persistently submit the order from the form in the UI Layer. This is a typical action in struts; observe the exception configuration in this action, which is also in the spring configuration file (applicationContext-hibernate.xml) (In the transactionattributes attribute of the business service object ). When exceptions are thrown at the business layer, we can control them and display them to the UI Layer as appropriate.

The first exception, orderexception, is triggered when the persistence layer fails to save the order object. This will cause the transaction to roll back and pass the exception back to the struts layer through Bo.

The second exception, orderminimumamountexception, is the same as the first exception.

The last step of integration is to combine the display layer with the business layer. This has been implemented by the service locator (discussed earlier). Here, the service layer serves as an interface for our business logic and persistence layer.

The saveneworder Action uses a service locator in struts to call the service execution method. The method code is as follows:

Code:
Public actionforward execute (

Actionmapping mapping,

Actionform form,

Javax. servlet. http. httpservletrequest request,

Javax. servlet. http. httpservletresponse response)

Throws java. Lang. Exception {

Orderform oform = (orderform) form;

// Use the form to build an order object that

// Can be saved in the persistence layer.

// See the full source code in the sample app.

// Obtain the wired business service object

// From the service locator Configuration

// In baseaction.

// Delegate the save to the service layer and

// Further upstream to save the order object.

Getorderservice (). saveneworder (order );

Oform. setorder (order );

Actionmessages messages = new actionmessages ();

Messages. Add (

Actionmessages. global_message,

New actionmessage (

"Message. Order. Saved. Successfully "));

Savemessages (request, messages );

Return Mapping. findforward ("success ");

}

Summary

This article covers a lot of underlying information in terms of technology and architecture. The main purpose of this article is to let you realize how to layer your applications. Layers can "decouple" your code-allow new components to be added, and make your code easy to maintain. The technology used here only focuses on solving the problem. In any case, using this architecture allows you to use other technologies to replace the current layer. For example, you may not use hibernate for persistence. Since you are programming interface-oriented in Dao, you can use ibatis instead. Alternatively, you may want to replace the current UI Layer with other technologies or frameworks other than struts, the Implementation Layer should not directly affect your business logic and business service layer ). Using an appropriate framework to build your web application is actually not a cumbersome task. What's more, it "decouples" all layers in your program.

Postscript:

After reading this article, I just thought I liked it very much, so I translated it. Of course, I was also prepared to get rid of the eggs that everyone threw :).

This article does not contain much technical details and detailed steps. If you have never used these frameworks before and encounter difficulties in running the instance program, you can post them on the csdn Forum Java open source edition. I will answer them in detail (ah, isn't it advertising ?),

This article describes how to use an existing open-source framework for layering from a framework perspective. I don't know how to express many terms, and many statements may have errors. If it affects your reading, please click the original article address and I am sorry for it.

Author profile: Mark Eagle Senior Software Engineer, Atlanta.
Totodo, Software Engineer
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.