Title: J2EE-based blog platform

Source: Internet
Author: User
Original technical experts-CompetitionArticle
Title: J2EE-based blog platform

[Comment]
Author: xuefengl (dev2dev ID)
Abstract:

This article describes how to create a blog system on the J2EE platform. the text function and interface are prototype, and springframework is the framework to implement a flexible multi-layer blog platform running on WebLogic Server.

Directory:

1. design objectives
2. Development Environment
2.1. Select the platform and framework
2.2. Configure the server
2.3. Compile the ant script
3. System Design
3.1. Persistence Layer Design
3.1.1. design domain objects
3.1.2. Configure ibatis
3.1.3. use DAO mode
3.2. logic layer design
3.3. Web Layer Design
3.3.1. Use the MVC Mode
3.3.2. Implement skin
3.3.3. upload images
3.3.4. Implement RSS
4. Test
5. Summary
6. Download source code
7. Download related resources
8. Reference
9. About the author

Design Objectives

Weblog is becoming more and more popular on the Internet. Many netizens have their own blogs to show themselves and meet more netizens. The famous blog platform is Asp.net-based open-source project. Text. However, all its logic is stored in the database as a stored procedure. Although stored procedures can greatly improve the efficiency of data operations, stored procedures are structured.ProgramAnd cannot exert the power of object-oriented, and is not easy to implement.CodeReuse. Therefore, I decided to implement a multi-layer structure blog platform based on the J2EE system. The function is very similar to the interface and. text, and is temporarily named Crystal blog. Common features include: multi-user support, publishing and editing articles, uploading images, and adding links. The interface is as follows:

Select platform and framework

We plan to use WebLogic Server 8.1 as the running platform and WebLogic workshop8.1 as the powerful Integrated ide as the development tool.
Select ms SQL Server 2000 sp3 as the database, and create a database named blog to store all user data. Since we do not have code for a specific database, we will test it later.
Before the system design, selecting an excellent framework can greatly improve the development efficiency. Spring is a Lightweight J2EE framework. It covers almost all aspects from the JDBC encapsulation of the back-end database to the front-end web framework. In addition, the coupling of various modules of spring is very loose. We can use it as the framework of the entire application, or just use one of its modules. In addition, spring's powerful integration feature allows us to easily integrate the Web end compiled by struts, or use hibernate as the back-end o/R Mapping solution.
The core idea of spring is IOC and AOP. spring itself is a lightweight container. Unlike EJB containers, spring components are common Java Beans, which makes unit tests no longer dependent on containers, it is easier to write. Spring manages all Java Bean components and also supports declarative transaction management. We only need to write the Java Bean components and then "Assemble" them. The initialization and Management of the components are completed by spring, and you only need to declare them in the configuration file. The biggest advantage of this method is that the coupling of various components is extremely loose, and we do not need to implement the singleton mode on our own.
Since relational databases are used to store data in the background, it is essential to use o/R Mapping. Ibatis is another o/R Mapping solution similar to hibernate. It features compact, simple configuration, flexible query, and fully meets our requirements.
In addition to spring and ibatis, third-party components used include common-file-upload 1.0 and rsslibj1.0 RC2.
Because spring is a lightweight framework, you don't need an EJB server. You only need a web server. Therefore, the system can run on WebLogic Server, tomcat, resin, and other Web servers that support Servlet and JSP.

Configuration server

Create a configuration in WebLogic, name it blog, and add a data source named JDBC/blog:

The directory structure of the entire application is as follows:
Crystalblog/
+ DOC/(store API Documentation)
+ Report/(store JUnit test results)
+ Src/(store the Java source program)
+ Web/(web directory)
| + Manage/(store the blog Management page)
| + Skin/(storing the blog page)
| + Upload/(stores user-uploaded images)
| + WEB-INF/
| + Classes/(stores compiled class files)
| + Lib/(store all jar files used)
| + C. TLD (use the files required by jstl)
| + Dispatcher-servlet.xml (Spring configuration file)
| + Web. XML (standard web configuration file)
+ Blog. War (packaged and deployable applications)
+ Build. XML (ANT script)

Compile an ant script

Ant is a great tool for executing batch processing tasks. Ant can be used to automate a series of tasks such as compilation, testing, packaging, deployment, and document generation, thus greatly saving development time.

First we put all the. Jar files used in/web/WEB-INF/lib, and then write the compile task, the generated class file directly put in the Web/WEB-INF/classes directory. If the compilation is successful, perform a unit test:

...

The unit test results are stored in the report directory as text files. If the test passes, the next step is to package it into the blog. War file. Then, deploy the application to the server and directly copy the content in the web directory to the % bea_home %/user_projects/domains/blogdomain/applications/blog/directory. To deploy tomcat, copy the entire web directory to % Tomcat %/webapps/blog.
Finally, you can use javadoc to generate API documents if needed.

System Design

Crystal blog is divided into three layers: The data persistence layer in the background and the DAO mode. The middle logic layer adopts the facade mode. The front-end web layer adopts the MVC structure and JSP as the view. The UML diagram of Rational Rose is as follows:

Design domain objects

The domain layer is an abstract entity. Based on the functions we want to implement, design the following entities, which are common Java Beans:
Account: encapsulate a user, including the user ID, user name, password, and user settings.
Category: encapsulates a category. There are three types of category used to manage article, image, and link respectively. An account corresponds to multiple category.
Article: encapsulate an article, including title, summary, content, etc. A category corresponds to multiple article.
Feedback: encapsulate a reply, including title, username, URL, and content. One Article corresponds to multiple feedback.
Image: encapsulate an image. The image only contains the image information (imageid, type). The specific image is stored as a file uploaded to the server. One category corresponds to multiple images.

Link: encapsulate a link. It has many to one relationship with category. It has attributes such as title, URL, and RSS.
Message: encapsulate a message so that other users can send emails to a user without knowing the email address.
Finally, we need a primary key to uniquely identify each database record. You can use auto-incrementing primary key generation methods in ms SQL Server and Oracle. However, many databases do not support auto-incrementing primary keys. Considering portability, we define a sequence table to generate auto-incrementing primary keys. The sequence table has only seven records, respectively recording the current maximum primary key value from the account to the message object. When the system starts, sqlconfig initializes the sequence table.
Sequencedao is responsible for providing the next primary key. To improve efficiency, 10 primary keys are cached at a time.

Configure ibatis

Next, use ibatis to implement o/R Mapping. First download ibatis 2.0 from the http://www.ibatis.com and copy the required JAR file to the Web/WEB-INF/lib/directory. Ibatis uses XML to configure the ing of the database table to the Java object, first write a sql-map-config.xml:
<? XML version = "1.0" encoding = "UTF-8"?>
<! Doctype sqlmapconfig
Public "-// ibatis.com//dtd SQL map config 2.0 // en"
Http://www.ibatis.com/dtd/sql-map-config-2.dtd>
<Sqlmapconfig>
<Settings cachemodelsenabled = "false" enhancementenabled = "true"
Lazyloadingenabled = "true" maxrequests = "32"
Maxsessions = "10" maxtransactions = "5"
Usestatementnamespaces = "false"
/>
<Transactionmanager type = "JDBC">
<Datasource type = "JNDI">
<Property name = "datasource" value = "JDBC/blog"/>
</Datasource>
</Transactionmanager>
<! -- If you have other xml configuration files, you can include them. -->
<Sqlmap resource = "account. xml"/>
</Sqlmapconfig>
Put the sql-map-config.xml in the Web/WEB-INF/classes/directory, ibatis will be able to find this configuration file, and then write an initialization class:
Public class sqlconfig {
Private sqlconfig (){}
Private Static final sqlmapclient sqlmap;
Static {
Try {
Java. Io. Reader reader = resources. getresourceasreader ("sql-map-config.xml ");
Sqlmap = sqlmapclientbuilder. buildsqlmapclient (Reader );
} Catch (exception e ){
E. printstacktrace ();
Throw new runtimeexception ("error initializing sqlconfig. Cause:" + E );
}
}
Public static sqlmapclient getsqlmapinstance (){
Return sqlmap;
}
}
Sqlmapclient encapsulates most operations to access the database. You can directly use sqlconfig. getsqlmapinstance () to obtain this unique instance.

Use DAO mode

To separate the logical layer and database persistence layer, define a series of Dao interfaces: accountdao, categorydao, articledao ...... Its implementation classes correspond to sqlmapaccountdao, sqlmapcategorydao, sqlmaparticledao ...... This completely disconnects the logic layer from the database access code. If you need other O/R Mapping solutions in the future, you can directly implement the New Dao interface to replace the existing sqlmapxxxdao.

Taking sqlmapaccountdao as an example, it is very simple to implement a login () method:
Public int login (string username, string password) throws authorizationexception {
Try {
Map map = new hashmap ();
Map. Put ("username", username );
Map. Put ("password", password );
Integer I = (integer) sqlmap. queryforobject ("login", MAP );
If (I = NULL)
Throw new runtimeexception ("failed: invalid username or password .");
Return I. intvalue ();
}
Catch (sqlexception sqle ){
Throw new runtimeexception ("SQL exception:" + sqle );
}
}
Define Login query in the account. xml configuration file:
<Select id = "login" parameterclass = "Java. util. Map" resultclass = "int">
Select [accountid] from [account] Where
[Username] = # username # And Password = # password #
</SELECT>

Logic layer design

Since the DAO mode has implemented all database operations, the business logic mainly checks the input and calls the DaO interface. Therefore, the business logic is a simple facade interface:
Public class facadeimpl implements facade {
Private accountdao;
Private articledao;
Private categorydao;
Private feedbackdao;
Private imagedao;
Private linkdao;
Private sequencedao;
}
For common getarticle () methods, facade simply calls the corresponding Dao interface:
Public Article getarticle (INT ArticleID) throws queryexception {
Return articledao. getarticle (ArticleID );
}
For operations that require authentication, such as the deletearticle () method, facade needs to first verify the user identity:
Public void deletearticle (identity ID, int ArticleID) throws deleteexception {
Article article = getarticleinfo (ArticleID );
If (article. getaccountid ()! = ID. getaccountid ())
Throw new authorizationexception ("Permission denied .");
Articledao. deletearticle (ArticleID );
}
To separate the user authentication logic, you can use the proxy mode or Spring AOP to implement it using methodinterceptor. However, because the logic is very simple, you can simply write it in one piece without using overly complicated designs.
So far, our blog has implemented all the background business logic and provided a unified facade interface. The front-end web layer only depends on this facade interface. In this way, the coupling between the web layer and the backend is very loose, even if the whole web layer is replaced.

Web Layer Design

Use MVC Mode

Although spring can easily integrate Struts, webworks, and other Web frameworks, spring itself provides a very good web framework that fully implements the MVC mode.
When spring uses a dispatcherservlet, all specific requests are forwarded to the dispatcherservlet, which is then processed by the corresponding controller. The controller returns a modelandview object (Because Java method calls can only return one result, the ref parameter is not supported, so the model and view object are returned together.) model is a Java object, usually map, and view is the logical name of the view, usually the JSP file name, however, you can also use velocity as a view. The returned view obtains the real file name through viewresolver.

First configure spring MVC, declare dispatcherservlet in Web. XML, and process all requests ending with. C:
<Web-app>
<Servlet>
<Servlet-Name> dispatcher </servlet-Name>
<Servlet-class> org. springframework. Web. servlet. dispatcherservlet </servlet-class>
<Load-on-startup> 1 </load-on-startup>
</Servlet>
<Servlet-mapping>
<Servlet-Name> dispatcher </servlet-Name>
<URL-pattern> *. C </url-pattern>
</Servlet-mapping>
</Web-app>
Spring will look for a file named WEB-INF under the dispatcher-servlet.xml, and we need to create this file:
<? XML version = "1.0" encoding = "UTF-8"?>
<! Doctype beans public "-// spring // DTD bean // en"
Http://www.springframework.org/dtd/spring-beans.dtd>
<Beans>
</Beans>
All Java Bean components used must be declared and configured in this file. The following is the bean for configuring URL ing:
<Bean id = "urlmapping"
Class = "org. springframework. Web. servlet. handler. simpleurlhandlermapping">
<Property name = "mappings">
<Props>
<Prop key = "/Article. c"> articlecontroller </prop>
</Props>
</Property>
</Bean>
All requests matching/Article. C will be processed by the bean named articlecontroller. You also need to declare this articlecontroller:
<Bean id = "articlecontroller" class = "example. viewarticlecontroller">
</Bean>
Viewarticlecontroller processes the request, generates a model, and selects a view:
Public class viewarticlecontroller implements controller {
Private facade;
Public void setfacade (facade) {This. Facade = facade ;}
Public modelandview handlerequest (httpservletrequest request,
Httpservletresponse response) throws exception {
// Obtain the parameters:
Int ArticleID = integer. parseint (request. getparameter ("ArticleID "));
// Use facade to process the request:
Article article = facade. getarticle (ArticleID );
// Generate model:
Map map = new hashmap ();
Map. Put ("article", article );
// Return the model and view name "skin/simple/article ":
Return new modelandview ("skin/simple/article", MAP );
}
}
Finally, the result of skin/simple/Article. jsp is displayed to the user.
We noticed that viewarticlecontroller does not search for or create a facade by itself, but is set by the container through the setfacade (facade) method. This is the so-called IOC (inversion of control) or dependency injection. The container initializes all components through the configuration file:
<! -- Declare a facade -->
<Bean id = "Facade" class = "example. Facade"/>
<! -- Declare a controller -->
<Bean id = "articlecontroller" class = "example. viewarticlecontroller">
<! -- Set the facade attribute for articlecontroller -->
<Property name = "Facade">
<! -- Import the reference of bean named facade -->
<Ref bean = "Facade"/>
</Property>
</Bean>
The above configuration file provides the following functions:
Facade facade = new facade ();
Viewarticlecontroller articlecontroller = new viewarticlecontroller ();
Articlecontroller. setfacade (facade );
But we don't have to write the above Code. We only need to install our components in the XML file. All components are managed by spring, and the default creation mode is Singleton, ensuring that one component has only one instance.

In addition, all custom exceptions are runtimeexception. The AOP provided by spring allows us to conveniently handle exceptions. Define exceptionhandler on the web layer to handle all exceptions and Display Error information to the user in a unified error. jsp. Therefore, you only need to throw an exception in the Code and do not have to handle the exception in the Controller at all:
<Bean id = "handlerexceptionresolver" class = "org. crystalblog. Web. exceptionhandler"/>

Implement skin

Many blog systems allow users to choose their preferred interface style. To implement the skin function, it is very simple to compile a JSP view for each skin, store it in the Web/skin/directory, and then return the corresponding JSP view in the controller:
String Skin = skinmanager. getskinmanager (). getskin (account. getskinid ());
Return new modelandview (skin + "viewarticle", MAP );
Currently, two skins are implemented. For simplicity, the path is hardcoded in skinmanager.

Upload images

You must be able to upload images. Therefore, the file upload function is required. The more common File Upload components are commons fileupload (http://jakarta.apache.org/commons/fileupload) and cos fileupload (http://www.servlets.com/cos), spring has fully integrated these two components, here we choose commons fileupload.
Since a post-uploaded form containing a file will send a multipart/form-data request to the server, you must explicitly tell dispatcherservlet how to handle multipartrequest. First declare a multipartresolver in the dispatcher-servlet.xml:
<Bean id = "multipartresolver"
Class = "org. springframework. Web. multipart. commons. commonsmultipartresolver">
<! -- Set the maximum size of the uploaded file to 1 MB -->
<Property name = "maxuploadsize">
<Value> 1048576 </value>
</Property>
</Bean>
In this way, once a request is a multipartrequest, it will be first processed by multipartresolver and then forwarded to the corresponding controller.
In uploadimagecontroller, transforming httpservletrequest to multiparthttpservletrequest makes it easy to get the file name and content:
Public modelandview handlerequest (httpservletrequest request, httpservletresponse response) throws exception {
// Transform to multiparthttprequest:
Multiparthttpservletrequest multipartrequest = (multiparthttpservletrequest) request;
// Obtain the file:
Multipartfile file = multipartrequest. GetFile ("file ");
// Get the file name:
String filename = file. getoriginalfilename ();
// Obtain the input stream:
Inputstream input = file. getinputstream ();
// Write the file...
}

Implement RSS

RSS is a standard XML file. The RSS reader can read this XML file to obtain information about the article, so that users can read the blog through the RSS reader instead of the browser, we only need to dynamically generate this XML file. Rsslibj is a small and practical Java library dedicated to reading and generating RSS. The size of rsslibj is only 25 kb.
Rsslibj is easy to use. First set the header of httpservletresponse, and then output XML through rsslibj:
Channel channel = new channel ();
Channel. setdescription (account. getdescription ());
Baseurl = baseurl. substring (0, N );
Channel. setlink ("http: // server-name/home. C? Accountid = "+ accountid );
Channel. settitle (account. gettitle ());
List articles = facade. getarticles (accountid, account. getmaxperpage (), 1 );
Iterator it = articles. iterator ();
While (it. hasnext ()){
Article article = (Article) it. Next ();
Channel. additem ("http: // server-name/Article. C? ArticleID = "+ Article. getarticleid (),
Article. getsummary (), article. gettitle ()
);
}
// Output XML:
Response. setcontenttype ("text/XML ");
Printwriter PW = response. getwriter ();
PW. Print (Channel. getfeed ("RSS "));
PW. Close ();

Test

Server Configuration: P4 1.4G, 512 m ddr, 100 M Ethernet, Windows XP Professional SP1.
The test servers are WebLogic Server 8.1, Tomcat 4.1/5.0, and Resin 2.1.1.
The test database is ms SQL Server 2000 sp3. If you use Oracle, DB2, MySQL, and other databases and the test is successful, please send me the SQL initialization script and detailed configuration process. Thank you.
Due to limited time, no further tuning of Chinese characters and operations was tested. WebLogic Server and ibatis have many optimization options. For detailed configuration, refer to the relevant documentation.

Summary

Spring is indeed an excellent J2EE framework. With Spring's powerful integration capabilities, we can easily design flexible multi-layer J2EE applications without complex EJB component support. Due to the rush of time and limited level, there will inevitably be many mistakes in this article. please correct me.

Source codeDownload

Source code can be downloaded from http://www.javasprite.com/crystal/blog-src.zip.

Download related resources

JDK 1.4.2 can be downloaded from the http://java.sun.com.
Spring Framework 1.1 can be downloaded from the http://www.springframework.org.
Ibatis 2.0 can be downloaded from the http://www.ibatis.com.
Tomcat 4.1/5.0, ant 1.6 can be downloaded from the http://www.apache.org.
Resin 2.1.1 can be downloaded from http://www.caucho.com.
WebLogic Server/Workshop 8.1 can be downloaded from the http://commerce.bea.com.
JUnit 3.8 can be downloaded from the http://www.junit.org.
MySQL 4 and its JDBC driver can be downloaded from http://www.mysql.com.
Ms SQL Server 2000 JDBC driver available from
Http://www.microsoft.com/downloads/details.aspx? Familyid = 07287b11-0502-461a-b138-2aa54bfdc03a & displaylang = en
Download.
The rsslibj 1.0 file can be downloaded from http://sourceforge.net/projects/rsslibj.

Reference

"Spring reference", Rod Johnson, etc.
"Ibatis SQL maps Guide ".
"Apache ant 1.6.2 manual ".
The springframework jpetstore example is a great design. This article describes many design patterns of jpetstore.

About the author
Liao Xuefeng, graduated from Beijing University of Posts and Telecommunications, have a strong interest in J2EE/J2EE, welcome to exchange: asklxf@163.com.
Personal site: http://www.javasprite.com, welcome to visit.
Personal blog site: http://blog.csdn.net/asklxf/. welcome to Alibaba Cloud.

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.