Anda di halaman 1dari 11

PORTFOLIO 3

ComS 319 Fall 2014

Group 5

Matthew Clucas
Michael Mead
Jacob Moyer

Porfolio III
Table of Contents
Introduction................................................................................................................ 2
Interaction with Materials........................................................................................... 2
Insights & Questions............................................................................................... 2
User Interface.......................................................................................................... 3
Home.jsp.............................................................................................................. 3
Complex Topics........................................................................................................... 3
Asynchronous Java Servlets.................................................................................... 3
Threads................................................................................................................... 3
Web Security........................................................................................................... 3
Cross-Site Scripting................................................................................................. 3
SQL Injection........................................................................................................... 3
Data Integrity.......................................................................................................... 4
Modular Design....................................................................................................... 4
Model-View-Controller (MVC) Pattern.......................................................................6
Blooms Taxonomy...................................................................................................... 7
Analysis................................................................................................................... 7
Evaluation............................................................................................................... 7
Synthesis................................................................................................................. 7
Creation................................................................................................................. 10

Introduction
This portfolio demonstrates the learning expectations of Java servlets, web security,
the Model View Control (MVC) design pattern, and thread synchronization. To
highlight our understanding of these concepts, we built a website where users can
play Stratego online against one another using over 10 themes! A scoring system is
also implanted to award points to users for winning games: a standard win based on
the rules of Stratego is worth 100 points, a win by an opponent quitting is worth 50
points, and a win by opponent network timeout is worth 25 points. Points for losses
are -25, -100, and -50 respectively. To build this site, we had to integrate several
technologies. MySQL server is used for our database, and Java is used for code on
the back-end. The front-end is comprised of html, css, js, and jsp. Understanding
how these technologies interact was crucial for the development of our final project.
The higher levels of Blooms Taxonomy are demonstrated by Stratego though its
creation, analysis, and evaluation.

Interaction with Materials


Insights & Questions
How do I use Java servlets?
How do I prevent security vulnerabilities, such as cross-site scripting and SQL
injection?
How do I set up threads for multiplayer?
How should I organize my code?
How do I keep my servlets decoupled from the front end?
How do I design my GUI?
How do I maintain my data integrity?

Figure 1: Game Instance of Batman vs Disney Princesses

User Interface
Home.jsp
The main view of our entire application is housed in home.jsp. This file uses Java to
generate css on the fly for all of the themes that a user could select, and also
utilizes Jquery and HTML to make post requests to our server. Starting a new game,
viewing the high scores, setting unit positions, moving positions, logging out, and
quitting a game are all done through a post request on home.jsp.

Complex Topics
Asynchronous Java Servlets
Asynchronous Java Servlets are the same as regular java servlets except they allow
the server to push multiple pieces of the response without ending the request. This
allows for a more dynamic response to be sent to the user. In order to do this we
have to set the configuration so that the servlet will handle asynchronous requests
through the AsyncContext object.

Threads
Threads were needed to allow multiple users to access the website and play the
game with each other. The threads need to be created, destroyed, and managed
properly to ensure that the website functions as intended. We dive into more detail
about the threads in our Blooms Taxonomy description.

Web Security
Cross-Site Scripting
With cross-site scripting, an attacker may make clients execute malicious
HTML/Javascript by passing this information into user inputs, effectively allowing for
phishing, local website defacement, cookie stealing, or session hijacking. As a
precaution to cross-site scripting, we escape any text that the user inputs before it
is published on the website. To do this, we use Javas
StringEscapeUtils.escapeHtml4 method.
<div class="navbar-right">
<p class="navbar-text">Signed in as <%
out.print(StringEscapeUtils.escapeHtml4(sessionUser)); %></p>
<button type="button" class="btn btn-default navbar-btn"
id="buttonLogout">Logout</button>
</div>

SQL Injection
To prevent SQL injection, we use prepared statements for all of our accesses to the
database. SQL injection allows an attacker to execute SQL that they write on the
database management system, effectively allowing them to modify the database.
This means they can add rows, read rows, or even delete entries, so it must be
taken seriously.
String sql = "INSERT INTO highscores (winner, loser, endType) VALUES (?, ?, ?)";
stmt = conn.prepareStatement(sql);

stmt.setString(1, winner);
stmt.setString(2, loser);
stmt.setString(3, endType.getEndType());

Data Integrity
In the back-end we ensure that if the user posts us bad data to handle it properly.
For example, if a user tries to edit the javascript to set an incorrect number of unit
types the back end will know what to do.
// make sure unit counts are correct
for (Integer count : unitCounts.values())
{
if (count.intValue() != 0)
{
logMsg("Cannot set positions for " + user + ", unit count is incorrect.");
rspMsg.setLogMsg("Unable to set positions: unit count is incorrect.");
output.print(rspMsg.getMessage());
output.flush();
return;
}
}

Modular Design
Modular design is very important in OOP. To achieve this, we use abstract classes to
allow decoupling between objects. A specific example is our ResponeMessage
abstract class which our servlets may extend to send to back a similarly formatted
JSON object for all responses. This way, the JavaScript may parse the response in a
similar manner each time and always know what to expect.
public abstract class ResponseMessage
{
protected JSONObject message = new JSONObject();
protected boolean isSuccessful = true;
protected String logMsg = null;
public ResponseMessage()
{
}
/**
* Returns the JSON string representation of this response message.
*
* @return
*/
public abstract String getMessage();
...
}
public class GameControlMessage extends ResponseMessage
{
private boolean isPingResponse = false;
private PlayerPosition position = null;

private
private
private
private
private
private
private

String opponent = null;


char[][] field = null;
boolean gameWon = false;
boolean gameLost = false;
PlayerPosition turn = null;
GameInstance game = null;
String opponentTheme = null;

...
/**
* Returns the JSON string representation of this response message.
*
* @return
*/
@Override
public String getMessage()
{
try
{
message.put("isSuccessful", isSuccessful);
message.put("logMsg", logMsg);
message.put("field", field);
if (game != null)
{
message.put("playerNum",
GameControlMessage.convertPlayerPosToPlayerNum(position));
message.put("opponent", game.getOpponent(position));
message.put("opponentTheme", game.getOpponentTheme(position));
message.put("gameWon", position.equals(game.getWinner()));
message.put("gameLost",
GameInstance.negatePosition(position).equals(game.getWinner()));
message.put("currentTurn",
GameControlMessage.convertPlayerPosToPlayerNum(game.getTurn()));
}
else
{
message.put("playerNum",
GameControlMessage.convertPlayerPosToPlayerNum(position));
message.put("opponent", opponent);
message.put("opponentTheme", opponentTheme);
message.put("gameWon", gameWon);
message.put("gameLost", gameLost);
message.put("currentTurn",
GameControlMessage.convertPlayerPosToPlayerNum(turn));
message.put("isPingResponse", isPingResponse);
}
}
catch (JSONException e)
{
e.printStackTrace();
}
return message.toString();
}

Model-View-Controller (MVC) Pattern


Developing Stratego with the MVC pattern was essential to allowing us to have well
organized code. The view is the website that is exposed to the user, and it is made
up of jsp, js, html, and css files. The view files are all placed in our WebContent
folder and separated from our models and controls. The models and controls are
written in java and are separated into different packages and files.

Figure 6: MVC Flow Diagram

Blooms Taxonomy
Analysis
Analysis of threading
What are threads, threading, and multi-threaded applications? Threading allows us
to perform multiple tasks at the same time. In java, threads may be created by the
following code:
Thread t = new Thread();
t.start();

This other thread will begin executing other code at the same time as the code that
ran this code.

Evaluation
Evaluation of threading
While threading is useful and sometimes the only way or the best way to do some tasks, it also presents a
new class of problems. Threads are used in web servers to allow multiple users to access the site at the
same time with quick response times, or could be used in almost any task where the task can be ran in
multiple parts at the same time. Problems can arise when threads attempt to use the same data at the
same time. This can be a very difficult problem to find and debug.

Synthesis
Synthesis of threading
To show how threading works, in our Stratego game, we use threads in multiple ways, and show how to
handle making the common data between them "thread-safe".
In our game each request from the user is responsible for reporting information back to that user. There is
a common game object between the two players in the game and when the game is changed in a way
that needs to be displayed to the other player, usually some sort of flag is set. The other player's thread
will poll this flag and act if it has changed. The following example is shown how this is done.
private void waitForPlayersTurn(final PrintWriter output, final GameControlMessage
rspMsg, final GameInstance game,
final PlayerPosition userPos)
{
if (game.getTurn() == null || game.getTurn().equals(userPos))
{
return;
}
// wait until the other player is done
while (game.getTurn() != null && !game.getTurn().equals(userPos))
{
// wait some time
try
{
logMsg(game.getPlayer(userPos) + " is waiting for " +
game.getOpponent(userPos)
+ " to finish their turn.");
// x1000 because sleep takes milliseconds
Thread.sleep(THREAD_SLEEP_SECONDS * 1000);
}

catch (InterruptedException e)
{
e.printStackTrace();
}
// display any message that has occured because of the other user
char[][] revealGrid = game.getBattleRevealGrid();
if (revealGrid != null)
{
rspMsg.setSuccessful(true);
rspMsg.setField(revealGrid);
rspMsg.setTurn(game.getTurn());
// prints the json response message
output.print(rspMsg.getMessage());
output.flush();
game.setBattleRevealGrid(null);
}

// need to check if the game is still going


if (game.getWinner() != null)
{
// display the winning results
rspMsg.setField(game.getBattleRevealGrid());
rspMsg.setGameWon(game.getWinner().equals(userPos));
rspMsg.setGameLost(game.getWinner().equals(GameInstance.negatePosition(userPos)));
}
else
{
rspMsg.setField(game.getFieldSymbolsByPlayer(userPos));
}
// its our turn now, display the new grid
rspMsg.setSuccessful(true);
rspMsg.setTurn(game.getTurn());

// prints the json response message


output.print(rspMsg.getMessage());
output.flush();

When a thread calls this method, it begins to wait for the player's turn to act in the game. It does this by
checking the game.getTurn() and checking if it has changed to this player's turn. Some issues can
happen when threads attempt to write to the same memory at the same time. When that happens, the
outcome is unpredictable and each thread might overwrite the other's work. In order to solve this, either
global flag variables available to both threads can be used as seen above, or in java there is the ability to
have synchronized blocks. The following shows an example of this in action.
private static final int INITIAL_USER_CAPACITY = 10;
private static final HashMap<String, Long> _users = new HashMap<String, Long>(
INITIAL_USER_CAPACITY);
public static void removeUser(final String user)

{
synchronized (_users)
{
_users.remove(user);
}
}
public static void putUser(final String user)
{
synchronized (_users)
{
_users.put(user, Validator.currentTimeSeconds());
}
}
Those synchronized blocks will not allow more than one thread to access that block of code at a time,
making sure that one thread's actions will be performed without interference by another thread. Putting
the (_users) makes sure that no other thread will enter that block of code while operating on the _users
object.
These features allow us to easily build what is known as a singleton for multiple threads. That is an object
that will only ever be created once. This is useful for us because it allows us to have a few data structures
that persist across the entire lifespan of the Stratego servlet's life. These include a HashMap that stores
all the games running, a HashMap of all the currently logged in users, a master controller object for all
games. Here is an example of how thread synchronization allows for a good singleton.
private static GameInstanceController _instController = null;
/**
* Get the singleton instance of GameInstanceController.
*
* @return
*/
public static GameInstanceController getInstanceController()
{
if (_instController == null)
{
synchronized (GameInstanceController.class)
{
if (_instController == null)
{
_instController = new GameInstanceController();
}
}
}
return _instController;
}
How this works is, the object is initially null, and there is no public constructor. To get the singleton
instance of the object you must call getInstanceController() which first checks if the object exists and then
initializes it if it is null. Putting the initialization inside of a synchronized block will make sure that no other
thread tries to initialize it. This design pattern is very useful if you only want to have a single object,
especially if the overhead for making the object is large.

Creation

The Stratego website is a complete application created from scratch using


Java Servlets
Generated asynchronous threads to handle multiple users
Performed security practices to prevent client-side scripting, SQL injection,
and maintain data integrity
Implemented a system to handle different response states from our server
Wrote new code following the Model-View-Controller framework
Created UI to allow users to choose one of several themes
Added a scoring system that ranks users based on how many games they
have won and how they won
Formulated patterns to relay information between the controllers and views

10

Anda mungkin juga menyukai