Software Engineering for Web Applications Sample Example
Transcript of Software Engineering for Web Applications Sample Example
![Page 1: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/1.jpg)
Software Engineering for Web ApplicationsSample Example
Denis Helic
![Page 2: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/2.jpg)
Terminology(1/2)
Lecture is not about
Web programmming using a particular programming language
e.g. PHP, Java
The Web today is an application platform
Therefore it is a subject to software application engineering
(2/57)
![Page 3: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/3.jpg)
Terminology(2/2)
Introduce an engineering method of developing Web applications
Collect requirements from users
Analyse requirements and decide on the server-side technology (PHP,Java, etc.)
Implement the system
(3/57)
![Page 4: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/4.jpg)
Sample Application - Requirements(1/2)
Web-based database of scientific publications
Used for managing of personal publication databases
Retrieving of publications in different formats
HTML, BibteX, XML
Searching for specific publications
Type, year, title keywords
(4/57)
![Page 5: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/5.jpg)
Sample Application - Requirements(2/2)
A special user as administrator
Can add authors
Can add publications
Delete, update!
Importing publications in different formats
BibteX, XML
(5/57)
![Page 6: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/6.jpg)
Selecting a server-side technology(1/2)
The Web is a specific application platform
HTTP is a connectionless protocol
Crucial to track user sessions
Managing user information over multiple requests
(6/57)
![Page 7: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/7.jpg)
Selecting a server-side technology(2/2)
PHP, Java provide high-level APIs for managing sessions
CGI-scripts do not have such high-level interfaces
You as a developer need to take care of that
Create unique session IDs and make them persistent on the serverside
Go for PHP or Java ;)
(7/57)
![Page 8: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/8.jpg)
Selecting a server-side storage(1/2)
Making application data persistent
Relational Database Managment Systems (RDBMS)
File system
Native XML databases
(8/57)
![Page 9: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/9.jpg)
Selecting a server-side storage(2/2)
Go for RDBMS because
ACID test (Atomicity, Consistency, Isolation, Durability)
Declarative query language SQL
You tell the system what do you want not how to do it!
Mature products, know-how, expirience, support, etc. (major prob-lem of native XML databases)
More on native XML databases in MMIS2
(9/57)
![Page 10: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/10.jpg)
Implementing the system - Engineering Method(1/3)
Pick a programming environment
Develop a data model
What data do I need to store and how I will represent it?
Comes down to developing a database schema, i.e., database tables
Develop a collection of legal transactions on the data model
How can I manipulate the data? (inserts, updates, selects, ... in SQL)
(10/57)
![Page 11: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/11.jpg)
Implementing the system - Engineering Method(2/3)
Design the page flow
How do users interact with the system?
Implement the individual pages
Accessing data
Wrap data in HTML
(11/57)
![Page 12: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/12.jpg)
Implementing the system - Engineering Method(3/3)
The biggest issue of all Web applications
Mixture of data access (content) and presentation
The goal to achieve
Separate content and presenatation
People have done it before → Design Patterns!
(12/57)
![Page 13: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/13.jpg)
Picking a programming environment(1/3)
Picking a RDBMS
Depends on requirements, know-how
Two choices: commercial and open source products
For the sample example I selected MySQL
Open Source, free, nice documentation
Performance not that critical since personal database (requirements)
(13/57)
![Page 14: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/14.jpg)
Picking a programming environment(2/3)
Picking an execution environment
CGI already gone because of session tracking
PHP or Java?
Database application - intelligent managing of database connections (per-formance)
Both PHP and Java can have connection pools
(14/57)
![Page 15: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/15.jpg)
Picking a programming environment(3/3)
PHP - scripting, interpreting, weakly type language
Fast to make the first implementation
Performance issues
Errors because of weak types, interpreter
Java technologies
Personal preference
OO, compiled, I can use JSP additionaly to have scripting!
(15/57)
![Page 16: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/16.jpg)
Developing a data model(1/4)
Managing of publications
Each publication has
One or more authors
Title
Year of publishing
Optionally URL
Type (depends on format)
(16/57)
![Page 17: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/17.jpg)
Developing a data model(2/4)
BibteX format http://www.din1505.informationskompetenz.net/
Types such as Article, Conference, Book, etc
Depending on type different additional attributes
Article has a journal
Book has a publisher, etc.
(17/57)
![Page 18: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/18.jpg)
Developing a data model(3/4)
One table for publications
Keeps data common for all publications
One table for persons involved
One publication can have many authors
One author can be involved in many publications
One table which relates a publication with its authors
One table which keeps additional attributes as key-value pairs
(18/57)
![Page 19: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/19.jpg)
Developing a data model(4/4)
Always provide an SQL script which initializes the database
Make sure that a new user is created and privileges are assigned
http://localhost:8080/publicationdb/src/setupdb.sql
(19/57)
![Page 20: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/20.jpg)
Define queries(1/3)
Analyse requirement to create queries
Select all publications
select * from publication;
select person.peid, name, role from pubperson, person
where pubperson.peid = person.peid and pubperson.pid = ?;
select * from pubattr where pid = ?;
(20/57)
![Page 21: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/21.jpg)
Define queries(2/3)
Select publications with a keyword in the title
select * from publication where title regexp ?;
select person.peid, name, role from pubperson, person
where pubperson.peid = person.peid and pubperson.pid = ?;
select * from pubattr where pid = ?;
(21/57)
![Page 22: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/22.jpg)
Define queries(3/3)
Insert a new publication
insert into publication values(null, ?, ?, ?, ?);
insert into pubperson values(?, ?, ?);
insert into pubattr values(?, ?, ?);
(22/57)
![Page 23: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/23.jpg)
Define the page flow(1/2)
Which user classes do I have?
“Normal” users
Can retrieve publications
Can use search form
(23/57)
![Page 24: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/24.jpg)
Define the page flow(2/2)
“Power” users
Navigation frame
Can insert a new person
Can insert a new publication (need to pick authors)
Can update an existing person
Can delete an existing person
Can update an existing publication
Can delete an existing publication
Authentication required
(24/57)
![Page 25: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/25.jpg)
Implement the individual pages
SQL statement problems
Authentication problems
Connection pools
Resolving content/presentation issue
Supporting different output formats
(25/57)
![Page 26: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/26.jpg)
SQL statement problems(1/4)
JDBC API provides the Statement class
Statement objects usually applied in the following way
Statement statement = connection.createStatement();
ResultSet result = statement.executeQuery(
"select * from publication where title regexp " +
request.getParameter("title"));
(26/57)
![Page 27: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/27.jpg)
SQL statement problems(2/4)
Usually long statements → typing errors
Security considerations
Suppose that users type “something ; select * from passwords;”
Performance issues
Each time the statement is compiled again!
(27/57)
![Page 28: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/28.jpg)
SQL statement problems(3/4)
Solution: use PreparedStatement class
select_pubs = connection.prepareStatement(
"select * from publication where title regexp ?");
select_pubs.setString(1, request.getParameter("title");
(28/57)
![Page 29: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/29.jpg)
SQL statement problems(4/4)
No typing errors
No need to compose the query string
Types are checked, e.g. setString(), setInt()
The security issue resolved
Parameter is used as a value of the query variable
Performance improved
PreparedStatment is pre-compiled only once
(29/57)
![Page 30: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/30.jpg)
Authentication problems(1/7)
DB authentication
Single DB user for all Web app users
Application logic resolves Web app authentication
Which users can access what pages?
(30/57)
![Page 31: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/31.jpg)
Authentication problems(2/7)
Types of Web app authentication
Programmatic authentication
Authentication hard-coded in the scripts
Declarative authentication
Declare username, passwords in a separate file
Let the servlet engine take care about authentication ;)
(31/57)
![Page 32: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/32.jpg)
Authentication problems(3/7)
Tomcat authentication
<security-constraint>
<display-name>
Publication Database Administration
</display-name>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/administrator/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>publicationdb</role-name>
</auth-constraint>
</security-constraint>
(32/57)
![Page 33: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/33.jpg)
Authentication problems(4/7)
Tomcat authentication (continued)
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/jsp_utils/login.jsp</form-login-page>
<form-error-page>
/jsp_utils/login_error.jsp
</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>publicationdb</role-name>
</security-role>
(33/57)
![Page 34: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/34.jpg)
Authentication problems(5/7)
Tomcat authentication (continued) tomcat-users.xml
<tomcat-users>
...
<role rolename="publicationdb"/>
...
<user username="pubadmin" password="admin"
roles="publicationdb"/>
...
</tomcat-users>
(34/57)
![Page 35: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/35.jpg)
Authentication problems(6/7)
DB authentication usually implemented in the following way
Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost/publicationdb",
"username", "password");
Problems
Security, portability
(35/57)
![Page 36: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/36.jpg)
Authentication problems(7/7)
A simple solution
Declare username and password as init-param in web.xml
Another problem of the previous approach
Performance since each request opens a new connection
A better solution
Resolve authentication issue together with connection pooling
(36/57)
![Page 37: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/37.jpg)
Connection pools(1/8)
Broker class encapsulates access to the database connections
getConnection() method
Behind the scene broker manages a buffer of connections
getConnection() returns the first available connection
If no free connection enlarge the buffer
When a client finishes it frees the connection (broker notified)
Optimizing the buffer size!
(37/57)
![Page 38: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/38.jpg)
Connection pools(2/8)
Usually JDBC drivers provide connection pooling
Apache Tomcat provides connection pooling
Database Connection Pool (DBCP)
Part of Jakarta Commons project
http://jakarta.apache.org/commons
(38/57)
![Page 39: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/39.jpg)
Connection pools(3/8)
DBCP uses Java Naming Directory Interface (JNDI)
JNDI Data Source
Define JNDI resource reference in web.xml
Map JNDI resource onto a real resource in server.xml
Lookup JNDI data source in the code
(39/57)
![Page 40: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/40.jpg)
Connection pools(4/8)
Define JNDI resource reference in web.xml
<resource-ref>
<res-ref-name>jdbc/publicationdb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
(40/57)
![Page 41: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/41.jpg)
Connection pools(5/8)
Map JNDI resource onto a real resource in server.xml
<Context path="/publicationdb" docBase="publicationdb"
debug="0" reloadable="true" >
<ResourceParams name="jdbc/publicationdb">
<parameter>
<name>username</name>
<value>publicationdb</value>
</parameter>
<parameter>
<name>password</name>
<value>mmis2004</value>
</parameter>
....
(41/57)
![Page 42: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/42.jpg)
Connection pools(6/8)
Map JNDI resource onto a real resource (continued)
<parameter>
<name>driverClassName</name>
<value>org.gjt.mm.mysql.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost/publicationdb</value>
</parameter>
</ResourceParams>
</Context>
(42/57)
![Page 43: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/43.jpg)
Connection pools(7/8)
Lookup JNDI data source in the code
Context init = new InitialContext();
Context ctx = (Context) init.lookup("java:comp/env");
DataSource ds = (DataSource) ctx.lookup("jdbc/publicationdb");
connection_ = ds.getConnection();
(43/57)
![Page 44: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/44.jpg)
Connection pools(8/8)
Be careful!
Need to notify the broker when finished
Do so by closing connection and all other DB resources
try {
....
} finally {
close(insert_person, result);
closeConnection();
}
(44/57)
![Page 45: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/45.jpg)
Resolving mixture of content/presentation
Different desing approaches (patterns) to resolve the problem
Model-View-Controller pattern
Applied in Struts framework (MMIS2)
J2EE Design patterns
http://java.sun.com/blueprints/corej2eepatterns/
index.html
Data Access Object (DAO) patternhttp://java.sun.com/blueprints/corej2eepatterns/
Patterns/DataAccessObject.html
(45/57)
![Page 46: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/46.jpg)
Data Access Object - DAO Pattern(1/8)
Encapsualtes all database access into a single class
CRUD interface (create, read, update, delete)
Works with transfer objects
TO reflect application logic
(46/57)
![Page 47: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/47.jpg)
Data Access Object - DAO Pattern(2/8)
Example of DAO CRUD interface
PersonDAO....
public void storePerson(Person person);
public Iterator readAllPersons();
public Person readPersonWithId(int id);
....
http://localhost:8080/publicationdb/src/edu/iicm/publication/
db/PersonDAO.java
(47/57)
![Page 48: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/48.jpg)
Data Access Object - DAO Pattern(3/8)
TO Person encapsulates the app logic....
public Person(int id, String name);
public String getName();
public void setName(String name);
....
http://localhost:8080/publicationdb/src/edu/iicm/publication/
Person.java
(48/57)
![Page 49: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/49.jpg)
Data Access Object - DAO Pattern(4/8)
Similar classes for Publicationhttp://localhost:8080/publicationdb/src/edu/iicm/
publication/db/PublicationDAO.java
Publication classhttp://localhost:8080/publicationdb/src/edu/iicm/
publication/Publication.java
(49/57)
![Page 50: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/50.jpg)
Data Access Object - DAO Pattern(5/8)
Code to access the DAOs and present the results (Search interface)....
String type = request.getParameter("type");
String year = request.getParameter("year");
String title = request.getParameter("title");
Iterator pubs = dao.readAllPubs(type, year, title);
while (pubs.hasNext()) {
Publication pub = (Publication) pubs.next();
out.println(pub.getStringRep(writer));
}
....
(50/57)
![Page 51: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/51.jpg)
Data Access Object - DAO Pattern(6/8)
Searching the databasehttp://localhost:8080/publicationdb/
Access codehttp://localhost:8080/publicationdb/select_pubs.jsp.txt
Presenatation codehttp://localhost:8080/publicationdb/pubs.jsp.txt
(51/57)
![Page 52: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/52.jpg)
Data Access Object - DAO Pattern(7/8)
To decouple the storage from DAO class work with interfaces
Work with Abstract Factory Pattern to obtain proper DAO instances
Allows you to move to another storage, e.g., XML native database
(52/57)
![Page 53: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/53.jpg)
Data Access Object - DAO Pattern(8/8)
Factoryhttp://localhost:8080/publicationdb/src/edu/iicm/
publication/db/DAOFactory.java
A particular implementationhttp://localhost:8080/publicationdb/src/edu/iicm/
publication/db/PublicationJDBCDAOImpl.java
(53/57)
![Page 54: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/54.jpg)
Providing different output formats(1/3)
To have different output formats use Visitor pattern
Publication is an abstract class with an abstract write method
Subclasses (Article, Book, ...) invoke an abstract method from an ab-stract Visitor
Subclasses of Visitor implement the method
Write out the proper format
(54/57)
![Page 55: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/55.jpg)
Providing different output formats(2/3)
New format → new Visitor
Creation of Visitor again Abstract Factory
Allows you to use the same code to write out HTML, BibteX, ...http://localhost:8080/publicationdb/export.jsp
(55/57)
![Page 56: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/56.jpg)
Providing different output formats(3/3)
Interfacehttp://localhost:8080/publicationdb/src/edu/iicm/
publication/writer/PublicationStringWriter.java
A particular implementationhttp://localhost:8080/publicationdb/src/edu/iicm/
publication/writer/PublicationStringHTMLWriterImpl.java
Factoryhttp://localhost:8080/publicationdb/src/edu/iicm/
publication/writer/PublicationWriterFactory.java
(56/57)
![Page 57: Software Engineering for Web Applications Sample Example](https://reader036.fdocuments.us/reader036/viewer/2022071600/613d18cf736caf36b7594694/html5/thumbnails/57.jpg)
Sample App
Still under constructionhttp://localhost:8080/publicationdb
Administration interfacehttp://localhost:8080/publicationdb/administrator
Current buildhttp://coronet.iicm.edu/mmis/examples/sewa/publicationdb.
war
(57/57)