SSH Framework Online Mall project The basic additions and deletions of the 2nd War, service and action extraction _java

Source: Internet
Author: User
Tags sessions in domain

The previous section of the SSH Framework Online Mall Project The integration of the 1th war Struts2, Hibernate4.3 and Spring4.2 We built the STRUTS2, hibernate, and spring development environments and successfully consolidated them together. This section mainly completes some basic additions and deletions, as well as service, DAO and action extraction.
1. Service-Level extraction
in the previous section, we simply wrote the Save and update methods at the service level, where we began to refine the code for that section and then extract the code for the service layer.
1.1 Perfect Categoryservice layer
The operation of the database is nothing more than additions and deletions, first of all, we have to improve the Categoryservice layer interface and implementation:

Categoryservice interface Public 
interface Categoryservice extends baseservice<category> {public 
 
 void Save ( Category Category); Insert public 
 
 void Update (Category Category),//update public 
 
 void Delete (int id);//Remove public 
 
 Category get (int id) ; Get a Category public 
 
 list<category> query ();//Get All Category 
 
} 

Specific implementation of the Categoryservice interface:

public class Categoryserviceimpl extends baseserviceimpl&lt;category&gt; implements Categoryservice {private session 
 
 Factory sessionfactory; 
 Spring will be injected into the public void Setsessionfactory (Sessionfactory sessionfactory) {this.sessionfactory = sessionfactory; 
 Protected session getsession () {//gets session from the current thread, and if not, creates a new session return Sessionfactory.getcurrentsession (); 
 @Override public void Save (Category Category) {getsession (). Save (Category); 
 @Override public void Update (Category Category) {getsession (). Update (Category);  @Override public void Delete (int id) {///* The first method has the disadvantage of not deleting it first. Object obj = getsession (). Get (Category.class, 
 ID); 
 if (obj!= null) {getsession (). Delete (obj); 
 }*/String hql = "Delete Category while Id=:id"; 
 GetSession (). CreateQuery (HQL)//. Setinteger ("id", ID)//. Executeupdate (); 
 @Override public Category get (int id) {return (Category) getsession (). Get (Category.class, id);@Override public list&lt;category&gt; query () {String hql = ' from Category '; 
 Return GetSession (). CreateQuery (HQL). List (); 
 } 
}

Implementation of 1.2 service layer extraction
After completing the Categoryservice, we will extract the base implementation of the service layer. The idea is this: We extract a basic interface baseservice and the implementation of the basic interface Baseserviceimpl, when the next development, if the need for new service, You just need to do two steps: First define a new interface xxxservice inherit Baseservice interface, this interface can add new abstract methods And then define a new implementation class Xxxserviceimpl inherit Baseserviceimpl and implement the Xxxservice interface. This is more convenient for project maintenance.
We first create the Baseservice interface based on the above Categoryservice interface:

Base interface Baseservice, using the generic public 
interface baseservice<t> {public 
 void Save (t); 
 
 public void Update (T-t); 
 
 public void Delete (int id); 
 
 Public T get (int id); 
 
 Public list<t> query (); 
} 

The implementation class of the Baseservice interface is then created based on the Categoryserviceimpl implementation class Baseserviceimpl:

/** * @Description TODO (Common module extraction) * @author eson_15 */@SuppressWarnings ("Unchecked") public class Baseservice The type of the current operation is stored in the impl&lt;t&gt; implements baseservice&lt;t&gt; {private Class clazz//clazz, which is generic T private sessionfactory 
 
 Sessionfactory; 
 Public Baseserviceimpl () {//The following three printing information can be removed, here is to see for yourself System.out.println ("This represents the current call to construct the method object" + this); 
 System.out.println ("Gets the parent class information for the current this object" + This.getclass (). Getsuperclass ()); 
 System.out.println ("Get the current this object's parent class information (including generic information)" + This.getclass (). Getgenericsuperclass ()); 
 Get the generic parameter type Parameterizedtype type = (Parameterizedtype) this.getclass (). Getgenericsuperclass (); 
 Clazz = (Class) type.getactualtypearguments () [0]; 
 public void Setsessionfactory (Sessionfactory sessionfactory) {this.sessionfactory = sessionfactory; 
 Protected session getsession () {//gets session from the current thread, and if not, creates a new session return Sessionfactory.getcurrentsession (); 
 @Override public void Save (t) {getsession (). Save (t); } 
 
 @Override public void Update (T-t) {getsession (). Update (t); 
 @Override public void Delete (int id) {System.out.println (Clazz.getsimplename ()); 
 String hql = "Delete" + clazz.getsimplename () + "as C where c.id=:id"; 
 GetSession (). CreateQuery (HQL)//. Setinteger ("id", ID)//. Executeupdate (); 
 @Override public T get (int id) {return (T) getsession (). Get (Clazz, id); 
 @Override public list&lt;t&gt; query () {String hql = ' from ' + clazz.getsimplename (); 
 Return GetSession (). CreateQuery (HQL). List (); 
 } 
 
}

After the extraction, we can rewrite the Categoryservice interface and the Categoryserviceimpl implementation class. As follows:

Categoryservice interface Inherits Baseservice interface Public 
interface Categoryservice extends baseservice<category> { 
 / * 
 * As long as the addition of Categoryservice itself required new methods, the public method has been in the Baseservice/ 
} 
 
/** 
 * @Description TODO (module's own business logic) 
 * @author eson_15 * * */Public 
class Categoryserviceimpl extends Baseserviceimpl <Category> implements Categoryservice { 
 
 / 
 * * Simply implement the new method in the Categoryservice interface, Public methods have been implemented in Baseserviceimpl/ 
} 

As you can see from the code, the new service only needs to inherit the Baseservice interface, and then add the business logic needed for the service in the interface. The new Serviceimpl only needs to inherit Baseserviceimpl and implement the new business logic.
But don't forget the very important point: to Modify the bean in the spring's configuration file Beans.xml.

<!--generic classes cannot be instantiated, so add lazy-init properties--> 
<bean id= "Baseservice" Cn.it.shop.service.impl.BaseServiceImpl "lazy-init=" true "> 
 <property name=" sessionfactory "ref=" Sessionfactory "/> 
</bean> 
 
<bean id=" Categoryservice "class=" Cn.it.shop.service.impl.CategoryServiceImpl "parent=" Baseservice "/> 

Kill the property in the original Categoryservice, then add the parent attribute, indicate the inherited Baseservice, and then configure the Baseservice to Sessionfactory to Baseservice. Also note that the set Lazy-init property is true because Baseservice is a generic class and generic classes cannot be instantiated. At this point, the service layer of extraction is done.

2. Service layer Add an account
just extracted the service layer, now we want to write a account (Administrator) service is very simple:
First write a accountservice interface to inherit Baseservice:

Public interface Accountservice extends baseservice<account> {//Note the generics in Baseservice are now account * 
 * As long as you add the new method that Accountservice itself requires, the public method is already in Baseservice. 
 

Then write a Accountserviceimpl implementation class to inherit the Baseserviceimpl implementation class and implement the Accountservice interface:

public class Accountserviceimpl extends baseserviceimpl<account> implements Accountservice { 
 * * * Only by implementing the new method in the Accountservice interface, public methods have been implemented in the Baseserviceimpl/ 
 
 //admin login function and later perfected 
} 

        Finally, add the following configuration to the Beans.xml file:
<bean id= "Accountservice" class= "Cn.it.shop.service.impl.AccountServiceImpl" parent= "Baseservice"/>&NBSP;  
         This has written a new service, and later need to add a service to follow this process, very convenient.
3. Action's extract
3.1 action to save data in domain (request,session,application, etc.)
        We know that in action you can go directly through the Actioncontext.getcontext () To get a Actioncontext object and then get the corresponding domain object from the object, or you can inject the corresponding domain object by implementing the Xxxaware interface. Let's take a look at both of these methods:

public class Categoryaction extends Actionsupport implements requestaware,sessionaware,applicationaware{private Cate 
 
 Gory category; 
 
 Private Categoryservice Categoryservice; 
 public void Setcategoryservice (Categoryservice categoryservice) {this.categoryservice = Categoryservice; 
 Public String Update () {SYSTEM.OUT.PRINTLN ("----update----"); 
 Categoryservice.update (category); 
 Return "index"; 
 Public String Save () {System.out.println ("----Save----"); 
 Return "index"; Public String Query () {//solution one, replace the original built-in object with the corresponding map, so that it is not dependent on the JSP, but the amount of code is larger//Actioncontext.getcontext (). put ("Catego Rylist ", Categoryservice.query ()); In the Request field//Actioncontext.getcontext (). GetSession (). Put ("CategoryList", Categoryservice.query ()); In the Session field//Actioncontext.getcontext (). Getapplication (). Put ("CategoryList", Categoryservice.query ()); Put it in the application domain//solution two, implement the corresponding interface (requestaware,sessionaware,applicationaware), let the corresponding map inject request.put ("CategoryliSt ", Categoryservice.query ()); 
 Session.put ("CategoryList", Categoryservice.query ()); 
 Application.put ("CategoryList", Categoryservice.query ()); 
 Return "index"; 
 Public Category GetCategory () {return Category; 
 public void Setcategory (Category Category) {this.category = Category; 
 Private map&lt;string, object&gt; request; 
 Private Map&lt;string, object&gt; session; 
 
 Private map&lt;string, object&gt; application; 
 @Override public void Setapplication (map&lt;string, object&gt; application) {this.application = Application; 
 @Override public void Setsession (map&lt;string, object&gt; sessions) {this.session = session; 
 @Override public void Setrequest (map&lt;string, object&gt; request) {this.request = Request; 
 } 
}

The

is also the Categoryaction class that consolidates the three frameworks in the previous section, where we add a query method in which we store the results of queries to the request field, session domain, and application field. The first method is implemented directly using Actioncontext, without implementing any interfaces, but with a large amount of code; The second method implements the Requestaware, Sessionaware, and Applicationaware interfaces, The three abstract methods that implement this interface inject request, session, and application into the appropriate member variables, so that you can store query results in the query method in the domain. This amount of code seems to be larger than the first method ... But we can draw, look down first.
We add a new query connection to the index.jsp to test whether the query results can be displayed:

&lt;%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%&gt; &lt;%@ taglib "uri=" http://java.sun.com/jsp /jstl/core "prefix=" C "%&gt; &lt;! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" &gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;my JSP ' Index . jsp ' starting page&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;a href= ${pagecontext.request.contextpath}/categ Ory_update.action?category.id=2&amp;category.type=gga&amp;category.hot=false "&gt; Access update&lt;/a&gt; &lt;a href=" Category_save.action "&gt; Access save&lt;/a&gt; &lt;a href=" category_query.action "&gt; Query all Categories &lt;/a&gt;&lt;br/&gt; &lt;c : ForEach items= "${requestscope.categorylist}" var= "category" &gt; ${category.id} | ${category.type} | ${category.hot} &lt;br/&gt; &lt;/c:forEach&gt; &lt;c:foreach items= "${sessionscope.categorylist}" var= "category" &G 
 T ${category.id} | ${category.type} | ${category.hot} &lt;br/&gt; &lt;/c:forEach&gt; &lt;c:foreach items= "${applicationscope.categoRylist} "var=" category "&gt; ${category.id} | ${category.type} | 
 ${category.hot} &lt;br/&gt; &lt;/c:forEach&gt; &lt;/body&gt; &lt;/html&gt;

3.2 Extraction Baseaction
just mentioned, the second method has a larger amount of code, but we can extract a baseaction that deals specifically with these domain-related operations.

public class Baseaction extends Actionsupport implements Requestaware,sessionaware,applicationaware { 
 
 protected Map<string, object> request; 
 Protected Map<string, object> session; 
 Protected map<string, object> application; 
 
 @Override public 
 void Setapplication (map<string, object> application) { 
 this.application = Application; 
 } 
 
 @Override public 
 void Setsession (map<string, object> sessions) { 
 this.session = session; 
 } 
 
 @Override public 
 void Setrequest (map<string, object> request) { 
 this.request = Request; 
 } 
} 

And then our own action. If you need to use these domain objects to store data, directly inherit baseaction, you can directly use the request, session, and application objects. So the revised categoryaction is as follows:

 public class Categoryaction extends Baseaction {private Category Category; 
 
 <pre name= "code" class= "Java" > Private categoryservice categoryservice; 
 public void Setcategoryservice (Categoryservice categoryservice) {this.categoryservice = Categoryservice; Public String Update () {SYSTEM.OUT.PRINTLN ("----update----"), categoryservice.update (category), return "index"; public string Save () {System.out.println ("----Save----"), return "index", and public string query () {Request.put (" CategoryList ", Categoryservice.query ()); Session.put ("CategoryList", Categoryservice.query ()); Application.put ("CategoryList", Categoryservice.query ()); Return "index";  Public Category GetCategory () {return Category.} public void Setcategory (Category Category) {this.category = Category; }}

        all subsequent action to use the request, session, and application fields, as long as you inherit baseaction directly, Very convenient.
3.3 Get Parameters (Modeldriven)
        We continue to look at the Categoryaction class, which has a member variable category, which is a pojo, defines the variable and writes the set and get methods so that the JSP page can be passed along the URL with a parameter that is a property in the Category object. such as Id,type, but the parameters in the URL must be written in Category.id, Category.type, and so on. So struts will automatically inject this write parameter into the Category object, and then we can use the Category object directly, but this is a bit cumbersome. We can use Modeldriven to solve the problem more conveniently.

 public class Categoryaction extends Baseaction implements modeldriven<category>{ 
 
 Private Category Category; 
 The Modeldriven interface must implement the Getmodel () method, which presses the returned item to the top of the stack @Override public Category Getmodel () {Category = new Category (); 
 return category; 
 
 } <pre name= "code" class= "Java" > Private categoryservice categoryservice; 
 public void Setcategoryservice (Categoryservice categoryservice) {this.categoryservice = Categoryservice; 
 Public String Update () {SYSTEM.OUT.PRINTLN ("----update----"); 
 Categoryservice.update (category); 
 Return "index"; 
 Public String Save () {System.out.println ("----Save----"); 
 Return "index"; 
 Public String query () {request.put ("CategoryList", Categoryservice.query ()); 
 Session.put ("CategoryList", Categoryservice.query ()); 
 Application.put ("CategoryList", Categoryservice.query ()); 
 Return "index"; } 
 
} 

So we don't have to take category.id this tedious parameter in the foreground JSP page, look at the modeldriven part of the JSP page:

&lt;%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%&gt; &lt;%@ taglib "uri=" http://java.sun.com/jsp /jstl/core "prefix=" C "%&gt; &lt;! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" &gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;my JSP ' Index . jsp ' starting page&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;a href= ${pagecontext.request.contextpath}/categ Ory_update.action?category.id=2&amp;category.type=gga&amp;category.hot=false "&gt; Access update&lt;/a&gt; &lt;a href=" Category_save.action?id=1&amp;type=haha&amp;hot=true "&gt; Test modeldriven&lt;/a&gt; &lt;a href=" Category_ Query.action &gt; Query All Categories &lt;/a&gt;&lt;br/&gt; &lt;c:foreach items= "${requestscope.categorylist}" var= "category" &gt; ${category.id} | ${category.type} | ${category.hot} &lt;br/&gt; &lt;/c:forEach&gt; &lt;c:foreach items= "${sessionscope.categorylist}" var= "category" &G 
 T ${category.id} | ${category.type} | ${category.hot} &lt;br/&gt; &lt;/c:forEach&gt; &lt;c:fOreach items= "${applicationscope.categorylist}" var= "category" &gt; ${category.id} | ${category.type} | 
 ${category.hot} &lt;br/&gt; &lt;/c:forEach&gt; &lt;/body&gt; &lt;/html&gt;

        test results are available to obtain catgory, and all Id,type and hot properties are assigned. We can see that by implementing the Modeldriven interface, we can easily carry parameters in the URL, the action only need to implement the Getmodel method, the new one to use the object returned. It is easy to think that there will be a lot of struts in the model to be obtained, so this piece we also want to extract into the baseaction.
3.4 extract Modeldriven to baseaction
        First we add the code for the Modeldriven section in Baseaction, as follows:

Because there are a lot of different model need to use Modeldriven, so here use the generics public class Baseaction&lt;t&gt; extends Actionsupport implements 
 requestaware,sessionaware,applicationaware,modeldriven&lt;t&gt; {protected map&lt;string, Object&gt; request; 
 Protected Map&lt;string, object&gt; session; 
 
 Protected map&lt;string, object&gt; application; 
 
 protected T model; 
 @Override public void Setapplication (map&lt;string, object&gt; application) {this.application = Application; 
 @Override public void Setsession (map&lt;string, object&gt; sessions) {this.session = session; 
 @Override public void Setrequest (map&lt;string, object&gt; request) {this.request = Request; @Override public T Getmodel () {///here by parsing the incoming T to new a corresponding instance parameterizedtype type = (Parameterizedtype) this. 
 GetClass (). Getgenericsuperclass (); 
 Class Clazz = (Class) type.getactualtypearguments () [0]; 
 try {model = (T) clazz.newinstance (); 
 catch (Exception e) {throw new RuntimeException (e); 
 }return model; 
 } 
}

After the extraction, the code in the Categoryaction will become less:

Inherits Baseaction and adds the generic public 
class Categoryaction extends baseaction<category> { 
 
 private Categoryservice Categoryservice; 
 
 public void Setcategoryservice (Categoryservice categoryservice) { 
 this.categoryservice = Categoryservice; 
 } 
 
 Public String Update () { 
 System.out.println ("----update----"); 
 Categoryservice.update (model);//directly use model return 
 "index"; 
 } 
 
 Public String Save () { 
 System.out.println ("----Save----"); 
 SYSTEM.OUT.PRINTLN (model); Use model return directly 
 "index"; 
 
 Public String query () { 
 request.put ("CategoryList", Categoryservice.query ()); 
 Session.put ("CategoryList", Categoryservice.query ()); 
 Application.put ("CategoryList", Categoryservice.query ()); 
 Return "index"; 
 } 
 
 

        Here, there is also a place to look uncomfortable, is categoryservice this member variable, it always exists in categoryaction, Because the method in the Categoryservice object is useful in the categoryaction, you must create the object and have a set method to inject it in. This leads to the disadvantage that if you have a lot of action to use Categoryservice, you have to create the object and set method in their action, and if you want to use several different service objects in one action, you have to create all , so it becomes very miscellaneous.
3.5 Extract service to baseaction
        for above issues , we will all the service objects in the project are extracted into the baseaction to create, so that the other action inherited baseaction, want to use what service directly to use it:

I categorized the contents of the baseaction into the public class Baseaction&lt;t&gt; extends Actionsupport implements Requestaware,sessionaware, 
 applicationaware,modeldriven&lt;t&gt; {//service object protected categoryservice categoryservice; 
 
 protected Accountservice Accountservice; 
 public void Setcategoryservice (Categoryservice categoryservice) {this.categoryservice = Categoryservice; 
 public void Setaccountservice (Accountservice accountservice) {this.accountservice = Accountservice; 
 }//domain object protected map&lt;string, object&gt; request; 
 Protected Map&lt;string, object&gt; session; 
  
 Protected map&lt;string, object&gt; application; 
 @Override public void Setapplication (map&lt;string, object&gt; application) {this.application = Application; 
 @Override public void Setsession (map&lt;string, object&gt; sessions) {this.session = session; 
 @Override public void Setrequest (map&lt;string, object&gt; request) {this.request = Request; }//modeldriven ProtecteD T model; 
 @Override public T Getmodel () {Parameterizedtype type = (Parameterizedtype) this.getclass (). Getgenericsuperclass (); 
 Class Clazz = (Class) type.getactualtypearguments () [0]; 
 try {model = (T) clazz.newinstance (); 
 catch (Exception e) {throw new RuntimeException (e); 
 return model; The categoryaction is more refreshing in this way: public class Categoryaction extends baseaction&lt;category&gt; {public String update ( 
 ) {System.out.println ("----update----"); 
 Categoryservice.update (model); 
 Return "index"; 
 Public String Save () {System.out.println ("----Save----"); 
 SYSTEM.OUT.PRINTLN (model); 
 Return "index"; 
 Public String query () {request.put ("CategoryList", Categoryservice.query ()); 
 Session.put ("CategoryList", Categoryservice.query ()); 
 Application.put ("CategoryList", Categoryservice.query ()); 
 Return "index"; 
 } 
 
}

One might ask, baseaction have so many service objects not redundant? This is not true, because the spring container will create this object even if it is not written in the baseaction, which is not related to it, instead, the service object is placed in the baseaction to facilitate the development of other action, And baseaction does not need to be matched to the Struts.xml file, because there is no JSP that will request baseaction, it simply lets other action to inherit.
And don't forget: it's about modifying the configuration in Beans.xml:

<!--If the type is prototype, the default is to create it when used, not automatically create--> 
<bean id= "baseaction" class= "cn.it.shop.action.BaseAction" when it is started Scope= "Prototype" > 
 <property name= "Categoryservice" ref= "Categoryservice" ></property> 
 <property name= "Accountservice" ref= "Accountservice" ></property> 
</bean> 
 
<bean id= " Categoryaction "class=" Cn.it.shop.action.CategoryAction "scope=" prototype "parent=" Baseaction "/>"

Add a new baseaction bean, all the service objects in the project as a property, the original categoryaction in the property to kill.
Later, if we want to write new xxxaction, directly inherit baseaction can, if xxxaction useful to a service, directly to use it, Only need to add a xxxaction corresponding bean in the Beans.xml file, configure the jump in Struts.xml file.

4. Change XML to annotations
we can see that as the project becomes more and more written, the configuration in the Beans.xml will be more and more, and many configurations have redundancy, in order to be more easy to develop, we now change the configuration of XML to the form of annotations, we first look at the configuration in Beans.xml:

These are the types of beans that we built before and when we extracted them, all of which need to be converted into annotations, and we'll replace them with a piece of the following: first, the service section, which has three: Baseservice, Categoryservice and Accountservice. Replace the following:


Then the corresponding part of the beans.xml can be killed. Next, modify the action section, which includes Baseaction, Categoryaction, and Accountaction three, which are replaced by the following:


And then kill the Beans.xml in the action part of the configuration, and finally in the Beans.xml file to add a configuration as follows, you can use the annotation.
<context:component-scan base-package= "Cn.it.shop ..." />
One might ask, why are service and action two different when using annotations? @service is used in the service and @controller is used in the action? It's the same thing, just to distinguish them from different layers of beans, to make it easier to read.

Source of the entire project download address: http://www.jb51.net/article/86099.htm

Original address: http://blog.csdn.net/eson_15/article/details/51297698

The above is the SSH Framework online Mall project the entire content of the 2nd war, I hope to help you learn, but also hope that we support the cloud habitat community.

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.