Web-development models - College of Computer and Information ...

roomagitatedInternet και Εφαρμογές Web

8 Δεκ 2013 (πριν από 3 χρόνια και 8 μήνες)

77 εμφανίσεις

D
omain
D
riven
W
eb
D
evelopment
W
ith
W
ebJinn

Sergei Kojarski

College of Computer & Information Science

Northeastern University


joint work with

David H. Lorenz


http://webjinn.org

Outline


Background


Problem


Solution


Conclusion


Future work & Projects

Beginning: Static Pages

In the beginning (1991), web was static. People
could only browse html pages and no other
interaction was allowed…..


Resource


Client

HTTP

Web
-
Server

Browser

Client
-
server interaction was specified by the
HTTP 0.9 protocol, in terms of a simple
request/response model…

BACKGROUND

What about interaction?

Web

App

Client

HTTP

Web Server

Browser

1.

HTTP was extended to allow user data in the
request string

2.

Web Server redirects requests to a server
-
side
application

3.

Application reads user data, performs server
-
side
actions and dynamically generates HTTP response

BACKGROUND

Web Application : closer look



An HTTP gateway to a server

side resource



Converts between HTTP and Resource terms



Normally, doesn’t have complex logic

BACKGROUND

Web

App

HTTP

Server

Resource

Web Development

Two developer teams:


Functionality


(e.g., Java, C, Perl)


Presentation


(e.g., XML, HTML)

BACKGROUND

Technology #1: CGI scripts

public void service(HttpServletRequest request, HttpServletResponse
response) {


String message=request.getParameter(“message”);


response.setContentType("text/html");


PrintStream rs = new PrintStream(response.getOutputStream());


rs.print(“
<html>
”);


rs.print(“

<body>
”);


if (message != null)


rs.print(“

<h1>
” + message + “
</h1>
”) ;


else


rs.print(“
<h1> No message! </h1>
”);


rs.print(“

</body>
”);


rs.print(“
</html>
”);

}

Presentation
(HTML) code is

embedded into
functionality code

BACKGROUND

Technology #2: Dynamic Pages

<% String message = request.getParameter(“message”); %>

<html>


<body>


<%if (message!=null) {%>


<h1>
<%=message%>

</h1>


<%} else {%>


<h1> No message! </h1>


<%}%>


</body>

</html>



Cleaner look



More friendly to web designers



Easier to change

Presentation and

functionality are
still tangled!

BACKGROUND

Theory and Practice


Well
-
understood


Simple
functionality


Interactions
patterns


Difficult to create


Complicated
implementations


No reusable
components

Concept

State of the art

BACKGROUND


Background


Problem


Solution


Conclusion


Future work & Projects

Outline

Schema

HTTP Resource

Schema

Functionality

server
-
side operations

Presentation


HTML response

Control


high
-
level control
-
flow

Functionality

Presentation

Control

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


Statement st = conn.createStatement();


ResultSet rs =


st.executeQuery("select name,email,message from guestbook");%>

<%if (rs.next() {%>


<!
--
BEGIN
-
CONTENT
-
VIEW
------------
>

<table width=100% border=0 cellspacing=1 cellpadding=1>

<%do {%>


<tr><td>Visitor: <a href='mailto: <%=rs.getString("emai")%>'>


<%=rs.getString("name")%></a></td></tr>


<tr><td><%=rs.getString("message")%></td></tr>

<%} while (rs.next());%>

</table>

<!
--
END
-
CONTENT
-
VIEW
--------------
>

<%} else {%>

<!
--
BEGIN
-
NO RECORDS
-
VIEW
-------
>




Guest book is empty.

<!
--
END
-
NO RECORDS
-
VIEW
---------
>


<%}


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
--------------------------
>

<%}%>

The Problem:


Tangling and Scattering

page code example:

name

email

message

Visitor:

<%=rs.getString(“email”)%>

<%=rs.getString(“name”)%>

<%=rs.getString(“message”)%>


PROBLEM

<!
--
BEGIN
-
FAIL
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
FAIL
-
VIEW
--------------------------
>

<!
--
BEGIN
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
--------------------------
>

Separation of concerns

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


PreparedStatement pst = conn.prepareStatement(


(“insert into guestbook (name,email,message) values (?,?,?)”);


pst.setString(1,request.getParameter(“name”);


pst.setString(2,request.getParameter(“email”);


pst.setString(3,request.getParameter(“message”);


pst.execute(); %>

<!
--
BEGIN
-
SUCCESS
-
VIEW
------------
>

Message was successfully added

<!
--
END
-
SUCCESS
-
VIEW
--------------
>


} finally {conn.close();}


} catch (Exception e) {%>

<%}%>

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


Statement st = conn.createStatement();


ResultSet rs =


st.executeQuery("select name,email,message from guestbook");%>

<%if (rs.next() {%>


<!
--
BEGIN
-
CONTENT
-
VIEW
------------
>

<table width=100% border=0 cellspacing=1 cellpadding=1>

<%do {%>


<tr><td> Visitor: <a href='mailto: <%=rs.getString("emai")%> '>


<%=rs.getString("name")%> </a></td></tr>


<tr><td> <%=rs.getString("message")%> </td></tr>

<%} while (rs.next());%>

</table>

<!
--
END
-
CONTENT
-
VIEW
--------------
>

<%} else {%>

<!
--
BEGIN
-
NO RECORDS
-
VIEW
-------
>




Guest book is empty.

<!
--
END
-
NO RECORDS
-
VIEW
---------
>


<%}


} finally {conn.close();}


} catch (Exception e) {%>

<%}%>

<form action="doInsert.jsp">

<tr><th colspan=2>New Message</th></tr>

<tr><td>Your Name</td><td><input type=text name="name"></tr>

<tr><td>E
-
mail</td><td><input type=text name="email"></tr>

<tr><td>Message</td><td><textarea name="message"></textarea>

<tr><td colspan=2><input type=submit value="Add"></td></tr>

</form>

select.jsp

doInsert.jsp

insertForm.jsp

name

email

message

name

email

message

pst.setString(1,request.getParameter(“name”);

<input type=text name="name">

Your Name

pst.setString(1,request.getParameter(“email”);


pst.setString(1,request.getParameter(“message”);

E
-
mail

Message

<input type=text name=“email">

<textarea name=“message"></textarea>

?,?,?

Visitor:

<%=rs.getString(“email”)%>

<%=rs.getString(“name”)%>

<%=rs.getString(“message”)%>

Main
contribution:
schema concern
modularization


PROBLEM

Example:Guestbook


PROBLEM

Example: Guestbook


Typical client
-
server interaction


Typical components (select, insert)


Typical problems


intra
-
crosscutting


inter
-
crosscutting


PROBLEM

Guestbook Architecture

Browser

guestbook

database table

SQL queries

select.jsp

doInsert.jsp

insertForm.jsp

HTTP


PROBLEM

Retrieves messages

A form for adding a
message

Posts a new message

Select records from
guestbook table


Print “Content”

Load driver and connect to
database

If table is not empty then

Else


Print “No records”

Close database connection

Catch exception


Print “Service not available”

select.jsp

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


Statement st = conn.createStatement();


ResultSet rs =


st.executeQuery("select name,email,message from guestbook");%>

<%if (rs.next() {%>


<!
--
BEGIN
-
CONTENT
-
VIEW
------------
>

<table width=100% border=0 cellspacing=1 cellpadding=1>

<%do {%>


<tr><td>Visitor: <a href='mailto: <%=rs.getString("emai")%>'>


<%=rs.getString("name")%></a></td></tr>


<tr><td><%=rs.getString("message")%></td></tr>

<%} while (rs.next());%>

</table>

<!
--
END
-
CONTENT
-
VIEW
--------------
>

<%} else {%>

<!
--
BEGIN
-
NO RECORDS
-
VIEW
-------
>




Guest book is empty.

<!
--
END
-
NO RECORDS
-
VIEW
---------
>


<%}


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
--------------------------
>

<%}%>

page code

description

name

email

message

Visitor:

<%=rs.getString(“email”)%>

<%=rs.getString(“name”)%>

<%=rs.getString(“message”)%>

select name, email, message from …

name

email

message

<%=rs.getString(“name”)%>

href=“

<%=rs.getString(“email”)%>

>

</a>

<%=rs.getString(“message”)%>

</td>


PROBLEM

Construct and execute

SQL insert statement


Print “Fail”

Print “Message added”

doInsert.jsp

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


PreparedStatement pst = conn.prepareStatement(


(“insert into guestbook (name, email, message) values (?,?,?)”);


pst.setString(1,request.getParameter(“name”);


pst.setString(2,request.getParameter(“email”);


pst.setString(3,request.getParameter(“message”);


pst.execute(); %>

<!
--
BEGIN
-
SUCCESS
-
VIEW
------------
>

Message was successfully added

<!
--
END
-
SUCCESS
-
VIEW
--------------
>


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
FAIL
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
FAIL
-
VIEW
--------------------------
>

<%}%>

Load driver and connect to
database

Close connection

Catch exception

page code

description

name

email

message

pst.setString(1,request.getParameter(“name”);

pst.setString(1,request.getParameter(“email”);


pst.setString(1,request.getParameter(“message”);

?,?,?


PROBLEM

insertForm.jsp

Return an HTML form

that the visitor can fill

in order to add a new
message into the

guestbook.

<form action="doInsert.jsp">

<table>


<tr><th colspan=2>New Message</th></tr>


<tr>


<td>Your Name</td>


<td><input type=text name="name">


</tr>


<tr>


<td>E
-
mail</td>


<td><input type=text name="email">


</tr>


<tr>


<td>Message</td>


<td><textarea name="message"></textarea>


</tr>

<tr><td colspan=2><input type=submit value="Add"></td></tr>

</table>

</form>

page code

description

<input type=text name="name">

Your Name

E
-
mail

Message

<input type=text name=“email">

<textarea name=“message"></textarea>


PROBLEM

Intra
-

versus inter
-
crosscutting


Intra


Tangling


Dynamic pages


Page scoped


OOP solution


Inter


Scattering


Dynamic and static


Crosscuts pages


AOP solution

All scheme
expressions relate to
the same instance

insertForm.jsp

select.jsp

doInsert.jsp

Illustration

<form action="doInsert.jsp">

<tr><th colspan=2>New Message</th></tr>

<tr><td>Your Name</td><td><input type=text name="name"></tr>

<tr><td>E
-
mail</td><td><input type=text name="email"></tr>

<tr><td>Message</td><td><textarea name="message"></textarea>

<tr><td colspan=2><input type=submit value="Add"></td></tr>

</form>

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


Statement st = conn.createStatement();


ResultSet rs =


st.executeQuery("select name,email,message from guestbook");%>

<%if (rs.next() {%>


<!
--
BEGIN
-
CONTENT
-
VIEW
------------
>

<table width=100% border=0 cellspacing=1 cellpadding=1>

<%do {%>


<tr><td> Visitor: <a href='mailto: <%=rs.getString("emai")%> '>


<%=rs.getString("name")%> </a></td></tr>


<tr><td> <%=rs.getString("message")%> </td></tr>

<%} while (rs.next());%>

</table>

<!
--
END
-
CONTENT
-
VIEW
--------------
>

<%} else {%>

<!
--
BEGIN
-
NO RECORDS
-
VIEW
-------
>




Guest book is empty.

<!
--
END
-
NO RECORDS
-
VIEW
---------
>


<%}


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
--------------------------
>

<%}%>

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


PreparedStatement pst = conn.prepareStatement(


(“insert into guestbook (name,email,message) values (?,?,?)”);


pst.setString(1,request.getParameter(“name”);


pst.setString(2,request.getParameter(“email”);


pst.setString(3,request.getParameter(“message”);


pst.execute(); %>

<!
--
BEGIN
-
SUCCESS
-
VIEW
------------
>

Message was successfully added

<!
--
END
-
SUCCESS
-
VIEW
--------------
>


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
FAIL
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
FAIL
-
VIEW
--------------------------
>

<%}%>

Tangling

Scattering

Dynamic pages

Dynamic and static

Page scoped

Crosscuts pages

OOP solution

AOP solution


PROBLEM


High
development
cost


High
maintenance
cost


Loss of reuse
opportunities

Increases dependency between
developer groups, error
-
prone, etc.

Natural language

Consequence of inter
-
crosscutting


PROBLEM

High
development
cost

High
maintenance
cost

Loss of reuse
opportunities

Changes to the schema trigger
complex code updates

Cost of schema changes out
-
weights reuse benefits

Outline


Background


Problem


Solution


Conclusion


Future work

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


PreparedStatement pst = conn.prepareStatement(


(“insert into guestbook (name,email,message) values (?,?,?)”);


pst.setString(1,request.getParameter(“name”);


pst.setString(2,request.getParameter(“email”);


pst.setString(3,request.getParameter(“message”);


pst.execute(); %>

<!
--
BEGIN
-
SUCCESS
-
VIEW
------------
>

Message was successfully added

<!
--
END
-
SUCCESS
-
VIEW
--------------
>


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
FAIL
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
FAIL
-
VIEW
--------------------------
>

<%}%>

Unweaving inter
-
crosscutting

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


Statement st = conn.createStatement();


ResultSet rs =


st.executeQuery("select name,email,message from guestbook");%>

<%if (rs.next() {%>


<!
--
BEGIN
-
CONTENT
-
VIEW
------------
>

<table width=100% border=0 cellspacing=1 cellpadding=1>

<%do {%>


<tr><td> Visitor: <a href='mailto: <%=rs.getString("emai")%> '>


<%=rs.getString("name")%> </a></td></tr>


<tr><td> <%=rs.getString("message")%> </td></tr>

<%} while (rs.next());%>

</table>

<!
--
END
-
CONTENT
-
VIEW
--------------
>

<%} else {%>

<!
--
BEGIN
-
NO RECORDS
-
VIEW
-------
>




Guest book is empty.

<!
--
END
-
NO RECORDS
-
VIEW
---------
>


<%}


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
--------------------------
>

<%}%>

<form action="doInsert.jsp">

<tr><th colspan=2>New Message</th></tr>

<tr><td>Your Name</td><td><input type=text name="name"></tr>

<tr><td>E
-
mail</td><td><input type=text name="email"></tr>

<tr><td>Message</td><td><textarea name="message"></textarea>

<tr><td colspan=2><input type=submit value="Add"></td></tr>

</form>

name

email

message

name

email

message

pst.setString(1,request.getParameter(“name”);

<input type=text name="name">

Your Name

pst.setString(1,request.getParameter(“email”);


pst.setString(1,request.getParameter(“message”);

E
-
mail

Message

<input type=text name=“email">

<textarea name=“message"></textarea>

?,?,?

Visitor:

<%=rs.getString(“email”)%>

<%=rs.getString(“name”)%>

<%=rs.getString(“message”)%>

Schema
-
related expressions are clustered by operation

select.jsp

doInsert.jsp

insertForm.jsp

Constructing SQL select
statement

Constructing SQL insert
statement

Rendering guest book
messages as HTML table

Rendering HTML form for
inserting a message

XP1

XP2

XP4

1
. Substitute clusters with schema
-
shy extension points

To unweave inter
-
crosscutting we…

2. Specify schema
-
related code in a separate module

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


PreparedStatement pst = conn.prepareStatement(


(“insert into guestbook (name,email,message) values (?,?,?)”);


pst.setString(1,request.getParameter(“name”);


pst.setString(2,request.getParameter(“email”);


pst.setString(3,request.getParameter(“message”);


pst.execute(); %>

<!
--
BEGIN
-
SUCCESS
-
VIEW
------------
>

Message was successfully added

<!
--
END
-
SUCCESS
-
VIEW
--------------
>


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
FAIL
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
FAIL
-
VIEW
--------------------------
>

<%}%>

<%@ page import="java.sql.*" %>

<%try{


Class.forName("org.gjt.mm.mysql.Driver").newInstance();


java.sql.Connection conn;


conn = DriverManager.getConnection(


"jdbc:mysql://localhost/database?user=login&password=pass");


try {


Statement st = conn.createStatement();


ResultSet rs =


st.executeQuery("select name,email,message from guestbook");%>

<%if (rs.next() {%>


<!
--
BEGIN
-
CONTENT
-
VIEW
------------
>

<table width=100% border=0 cellspacing=1 cellpadding=1>

<%do {%>


<tr><td> Visitor: <a href='mailto: <%=rs.getString("emai")%> '>


<%=rs.getString("name")%> </a></td></tr>


<tr><td> <%=rs.getString("message")%> </td></tr>

<%} while (rs.next());%>

</table>

<!
--
END
-
CONTENT
-
VIEW
--------------
>

<%} else {%>

<!
--
BEGIN
-
NO RECORDS
-
VIEW
-------
>




Guest book is empty.

<!
--
END
-
NO RECORDS
-
VIEW
---------
>


<%}


} finally {conn.close();}


} catch (Exception e) {%>

<!
--
BEGIN
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
------------------------
>


Server error: <%=e.getMessage()%>

<!
--
END
-
SERVICE
-
NOT
-
AVAILABLE
-
VIEW
--------------------------
>

<%}%>

<form action="doInsert.jsp">

<tr><th colspan=2>New Message</th></tr>

<tr><td>Your Name</td><td><input type=text name="name"></tr>

<tr><td>E
-
mail</td><td><input type=text name="email"></tr>

<tr><td>Message</td><td><textarea name="message"></textarea>

<tr><td colspan=2><input type=submit value="Add"></td></tr>

</form>

XP1

XP2

XP3

XP4

Abstract application

Schema

Weaver

XP3

3. Employ weaver to produce executable code

XP Model


SOLUTION

Unweaving intra
-
crosscutting

Resource

Model

Controller

View

HTTP

request

response

Action classes

JSP pages

Controller

servlet

Web
-
application

Selects action class to
handle request
received

Performs server
-
side
operations. Deposit
results in web
-
tier
containers.

Selects appropriate
JSP view

Obtains data from
web
-
tier containers
and renders the
HTTP response

Structure concern

cuts across action

classes and JSP views

DDD model


SOLUTION

DDD = MVC + XP

What about having
one

model

that solves
both

problems?

Solution space


SOLUTION

Problem

Model

Framework

Intra
-
crosscutting

MVC

Apache Struts

Inter
-
crosscutting

XP

WebJinn/XP

Intra
-

and
Inter
-
crosscutting

DDD

WebJinn

WebJinn Architecture

Resource

Model

Controller

View

request

response

Java classes

JSP pages

Controller

servlet

Schema


SOLUTION

Benefits of WebJinn


Decreased dependency between
developer groups


Adaptability to schema changes


High code reusability.


Web components!


SOLUTION

Dynamic

page

DDD

Conclusion


CONCLUSION

Intra
-
crosscutting

Inter
-
crosscutting

Static

page

CGI scripts

MVC

XP

Future Work and Projects


Web AOP Project


AOP language design


Implementation of language semantics


Weaver implementation


Documentation


Web components project


Webjinn Component builder (use BeanBox)


Eclipse plugin development


Related projects: Content Management System.

Related Models & Frameworks


Apache Struts


Java Server Facets


The MVC Model


JSP & Servlet technology


ASP, PhP and other dynamic page
technologies


RELATED WORK