Инструкция для администратора

Задание

Разработка программы “Система учета прохода в здание” в среде NetBeans, которая включает в себя операции: проверка допуска в здание, запрос количества людей в здании, присутствие конкретного человека и ведение журнала посещений. Сериализуемый объект – смарт-карта (имя, номер). В дополнительную часть задания входило создание web-услуги, позволяющей полное клиентское взаимодействие, с помощью обмена данными JSON формата.

Описание программы

В ходе работы была реализована программа “Система учета прохода в здание”, визуальная часть программы представляет собой jsp-страницу, которая содержит в себе html-разметку и java-код, позволяющий использовать операции удаленного объекта. Приложение написано таким образом, что все действия и результаты выводятся на главной странице, это реализовано с помощью javascript и библиотеки jQuery. Так же с помощью web-cервиса, можно подсоединить любое количество клиентов, которые могут взаимодействовать с сервисом одновременно. Данные сервис был реализован с использованием JSON сообщений.

UML-диаграмма

инструкция для администратора - student2.ru инструкция для администратора - student2.ru

Web-сервис

Для создания дополнительного модуля взаимодействия клиента с сервером, была изменена аннотация Stateless на Stateful. Это было сделано для того, чтобы можно было хранить сеансовое состояние. С помощью него мы можем отслеживать подключившихся пользователей.

Взаимодействие с клиентом происходит в два этапа:

1) Клиент обращается к сервису, используя GET/POST запрос, и передаёт свою пару логин/пароль. В случае аутентификации, сервер отдаёт токен (ключ), для дальнейшего взаимодейстия и обмена данными. При неправильной паре логин/пароль сервер выдаёт ошибку.

2) Последующий обмен происходит с помощью полученного ключа.

Для общения с сервером была создана специальная страничка connect.jsp. Через которую и проходят все обращения к серверу.

Протокол взаимодействия с сервером.

Запрос Ответ в формате JSON
Для аутентификации и получения токена, обращение к серверу происходит по адресу: http://localhost:8080/AccessInBuilding-war/connect.jsp?auth_login=client& auth_pwd=pwd_client . В адресе указываются логин и пароль клиента. {“ token”: “token_key”} – при корректной аутентификации {“error”: ”202”} – ошибка, пара логин/пароль не корректны
Количество людей в здании: http://localhost:8080/AccessInBuilding-war/connect.jsp?token= token_key&type=act {“cnt”: “n”} – количество людей, например, {“cnt”: “3”} {“error”: “303”} –ошибка, сервер не отвечает
Проверка наличия пользователей в здании: http://localhost:8080/AccessInBuilding-war/connect.jsp?token= token_key&type=users {“users”: “data”} – возвращается таблица пользователей в здании - data. {“error”: “404”} –ошибка, сервер не отвечает
Лог посещений здания: http://localhost:8080/AccessInBuilding-war/connect.jsp?token= token_key&type=logs {“ logs”: “data”} – возвращается таблица логов посежений всех пользователей - data. {“error”: “505”} –ошибка, сервер не отвечает
Добавить пользователя в БД: http://localhost:8080/AccessInBuilding-war/connect.jsp?token= token_key&type=add&name=name&code=code В дополнительных параметрах name и code мы указываем имя и код сотрудника соответственно. {“ data”: “done”} – возвращается done при успешном занесении в базу. {“error”: “101”} –ошибка, сервер не отвечает
Проверка допуска в здание по имени/коду: http://localhost:8080/AccessInBuilding-war/connect.jsp?token= token_key&type=add&name=name&code=code В дополнительных параметрах name и code мы указываем имя и код сотрудника соответственно. {“ data”: “user_id”} – при нахождении пользователя в базе, возвращается его user_id (идентификатор пользователя). {“error”: “101”} –ошибка, сервер не отвечает.
Изменение статуса положения пользователя (в здании/нет в здании): http://localhost:8080/AccessInBuilding-war/connect.jsp?token= token_key&type=update_act&id=user_id&act=act В дополнительных параметрах user_id и act мы указываем идентификатор пользователя и новый статус сотрудника соответственно. {“ data”: “done”} – возвращается done при успешном изменении статуса. {“error”: “101”} –ошибка, сервер не отвечает


С помощью данного протокола любой клиент, написанный на любом языке программирования, может настроить полное взаимодействие с сервисом.

Серверная часть, разработанная на PHP.

Визуальная часть выполнена на сто процентов совпадающая с визуальным выводом сервера. Тут даже используюстя стили, javascript и библиотеки, взятые на прямую с сервера. Только javascript js.js, управляющий выводом сервисов не экран, был настроен для взаимодействия с сервером (через файл connect.php). Для этого был создан класс ConnectLogin(). Который конектится к серверу, аутентифицируется, сохраняет сессионные куки от сервера и сохраняет токен переданный от сервера в своих куках. После чего, по средствам токена (ключа), происходит динамическое обращение к серверу.

Данный класс содержит в себе 4-е метода:

1) ConnectLogin() - Автоматическое соединение с сервером и получение токена. Если токен получен, то будет исполь он, если нет, то по средствам функции curl производиться соединение и обмен с сервером. Это происходит при объявлении класса.

2) Autorization() – метод для авторизации с сервером. Вызывается в ConnectLogin().

3) getData($type="act", $opt=array()) – метод для обмена информации с сервером по средствам curl.

4) disconect() – деструктор класса. Удаляет токен.

Вывод на экран полученных данных происходит динамически по средствам технологии AJAX и использованием бибилиотеки jQuery.

1) Инструкция для пользователя

  1. Добавить пользователя в систему:

Кнопка “Добавить нового пользователя”, выводит на экран форму. В появившейся форме вводим «Имя Пользователя» (обязательный параметр) и «Код» (не обязательный параметр), нажимаем кнопку “Добавить пользователя”. Если операция прошла успешно, то появляется сообщение “Пользователь добавлен” и изменяется цвет формы, если произошла ошибка, то выводится сообщение об ошибке.

  1. Проверка допуска в здание по имени/коду:

В строке поиска можно ввести «Имя Пользователя» или его «Код» и нажать кнопку “Найти”. Результат поиска появляется под строкой поиска.

  1. Количество людей в здании:

Выводится автоматически при загрузке приложения, находится под строкой поиска.

  1. Проверка наличия пользователей в здании:

Выводится автоматически при загрузке приложения, находится под строкой количества людей в здании.

  1. Лог посещений здания:

Кнопка “Лог посещаемости”: при нажатии разворачивает лог посещений здания (дата, имя и примечание).

Исходный код

Серверная часть

AccessInBuilding-ejb – модуль EJB:

Access.java

package accessinbuilding;

import java.io.Serializable;

import javax.persistence.Basic;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.NamedQueries;

import javax.persistence.NamedQuery;

import javax.persistence.Table;

import javax.validation.constraints.NotNull;

import javax.validation.constraints.Size;

import javax.xml.bind.annotation.XmlRootElement;

@Entity

@Table(name = "ACCESS")

@XmlRootElement

@NamedQueries({

@NamedQuery(name = "Access.findAll", query = "SELECT a FROM Access a ORDER BY a.act DESC"),

@NamedQuery(name = "Access.findById", query = "SELECT a FROM Access a WHERE a.id = :id"),

@NamedQuery(name = "Access.findByCode", query = "SELECT a FROM Access a WHERE a.code = :code"),

@NamedQuery(name = "Access.findByName", query = "SELECT a FROM Access a WHERE a.name = :name"),

@NamedQuery(name = "Access.findByAct", query = "SELECT a FROM Access a WHERE a.act = :act"),

/* Поиск людей в здании*/

@NamedQuery(name = "Access.findCountAct", query = "SELECT a FROM Access a WHERE a.act > 0"),

/* Поиск по имени И коду. Если одного из параметров нет, то поиск идёт только по одному из параметров*/

@NamedQuery(

name = "Access.findByAccess",

query = "SELECT a FROM Access a WHERE (a.code = :code AND a.name = :name AND :code > 0 AND :name != '') OR (a.code = :code AND :code > 0 AND :name = '') OR (a.name = :name AND :code <= 0 AND :name != '')"

)

})

public class Access implements Serializable {

private static final long serialVersionUID = 1L;

@Id

@Basic(optional = false)

@NotNull

@Column(name = "ID")

@GeneratedValue

private Integer id;

@Basic(optional = false)

@NotNull

@Column(name = "CODE")

private int code;

@Basic(optional = false)

@NotNull

@Size(min = 1, max = 120)

@Column(name = "NAME")

private String name;

@Basic(optional = false)

@NotNull

@Column(name = "ACT")

private int act;

public Access() {

}

public Access(Integer id) {

this.id = id;

}

public Access(Integer id, int code, String name, int act) {

this.id = id;

this.code = code;

this.name = name;

this.act = act;

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public int getCode() {

return code;

}

public void setCode(int code) {

this.code = code;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAct() {

return act;

}

public void setAct(int act) {

this.act = act;

}

@Override

public int hashCode() {

int hash = 0;

hash += (id != null ? id.hashCode() : 0);

return hash;

}

@Override

public boolean equals(Object object) {

if (!(object instanceof Access)) {

return false;

}

Access other = (Access) object;

if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {

return false;

}

return true;

}

@Override

public String toString() {

return "accessinbuilding.Access[ id=" + id + " ]";

}

}

Log.java

package accessinbuilding;

import java.io.Serializable;

import java.util.Date;

import javax.persistence.Basic;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToOne;

import javax.persistence.NamedQueries;

import javax.persistence.NamedQuery;

import javax.persistence.Table;

import javax.persistence.Temporal;

import javax.persistence.TemporalType;

import javax.validation.constraints.NotNull;

import javax.validation.constraints.Size;

import javax.xml.bind.annotation.XmlRootElement;

@Entity

@Table(name = "LOG")

@XmlRootElement

@NamedQueries({

@NamedQuery(name = "Log.findAll", query = "SELECT l FROM Log l ORDER BY l.date DESC"),

@NamedQuery(name = "Log.findById", query = "SELECT l FROM Log l WHERE l.id = :id"),

@NamedQuery(name = "Log.findByDate", query = "SELECT l FROM Log l WHERE l.date = :date"),

@NamedQuery(name = "Log.findByDescr", query = "SELECT l FROM Log l WHERE l.descr = :descr")})

public class Log implements Serializable {

private static final long serialVersionUID = 1L;

@ManyToOne

@NotNull

private Access assignedAccess;

public Access getAssignedAccess() {

return assignedAccess;

}

public void setAssignedAccess(Access access) {

this.assignedAccess = access;

}

@Id

@Basic(optional = false)

@NotNull

@GeneratedValue

@Column(name = "ID")

private Integer id;

@Basic(optional = false)

@NotNull

@Column(name = "DATE")

@Temporal(TemporalType.DATE)

private Date date;

@Basic(optional = false)

@NotNull

@Size(min = 1, max = 120)

@Column(name = "DESCR")

private String descr;

public Log() {

}

public Log(Integer id) {

this.id = id;

}

public Log(Integer id, Date date, String descr) {

this.id = id;

this.date = date;

this.descr = descr;

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public Date getDate() {

return date;

}

public void setDate(Date date) {

this.date = date;

}

public String getDescr() {

return descr;

}

public void setDescr(String descr) {

this.descr = descr;

}

@Override

public int hashCode() {

int hash = 0;

hash += (id != null ? id.hashCode() : 0);

return hash;

}

@Override

public boolean equals(Object object) {

if (!(object instanceof Log)) {

return false;

}

Log other = (Log) object;

if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {

return false;

}

return true;

}

@Override

public String toString() {

return "accessinbuilding.Log[ id=" + id + " ]";

}

}

Act.jsp

<%@page contentType="text/html" pageEncoding="utf-8"%>

<%@page import="javax.naming.*, accessinbuilding.*" %>

<%@page errorPage="err.jsp"%>

<%!

AccessInBuildingSessionRemote ejbRef;

%>

<%

InitialContext ic = new InitialContext();

ejbRef = (AccessInBuildingSessionRemote)ic.lookup("accessinbuilding.AccessInBuildingSessionRemote");

int cnt = ejbRef.findCountAct();

%>

<%=cnt%>

Add.jsp

<%@page contentType="text/html" pageEncoding="utf-8"%>

<%@page import="javax.naming.*, accessinbuilding.*" %>

<%@page errorPage="err.jsp"%>

<%!

AccessInBuildingSessionRemote ejbRef;

%>

<%

InitialContext ic = new InitialContext();

ejbRef = (AccessInBuildingSessionRemote)ic.lookup("accessinbuilding.AccessInBuildingSessionRemote");

ejbRef.addAccess( request.getParameter("name"), Integer.parseInt(request.getParameter("code")) );

%>

done

Err.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>

error

Find.jsp

<%@page contentType="text/html" pageEncoding="utf-8"%>

<%@page import="javax.naming.*, accessinbuilding.*" %>

<%@ page errorPage="err.jsp"%>

<%!

AccessInBuildingSessionRemote ejbRef;

%>

<%

InitialContext ic = new InitialContext();

ejbRef = (AccessInBuildingSessionRemote)ic.lookup("accessinbuilding.AccessInBuildingSessionRemote");

int findID = ejbRef.findByNameOrCode( request.getParameter("name"), Integer.parseInt(request.getParameter("code")) );

%>

<%=findID%>

Index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

<title>Система учета прохода в здание</title>

<link href="css.css" type="text/css" rel="stylesheet" />

<link href="css/jquery-ui-1.9.1.custom.css" type="text/css" rel="stylesheet">

<script src="jquery-1.8.2.min.js"></script>

<script src="jquery-ui.js"></script>

<script type='text/javascript'>jQuery.noConflict();</script>

<script src="js.js"></script>

</head>

<body>

<table border="0" cellpadding="0" cellspacing="0" width="700" align="center" class="body">

<tr>

<td>

<h1>Система учета прохода в здание</h1>

<div align="right" class="add_b">

<div align="right">Добавить нового пользователя</div>

</div>

<form action="add.jsp" method="post" enctype="multipart/form-data" class="add_form">

Имя<sup>*</sup>: <input type="text" name="name" id="add_name" value="" />

&nbsp;Код: <input type="text" name="code" id="add_code" value="" />

<input type="submit" value="Добавить пользователя" class="add" /><span class="add_load">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

<div class="add_err"></div>

</form>

<form action="find.jsp" method="post" enctype="multipart/form-data" class="find_form">

Имя<sup>*</sup>: <input type="text" name="name" id="find_name" value="" />

&nbsp;Код: <input type="text" name="code" id="find_code" value="" />

<input type="submit" value="Найти" class="find" /><span class="find_load">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

<div class="find_err">Поиск пользователя, например: <span>Иванов Иван</span> </div>

</form>

<br>

<div class="cnt_act"></div>

<div class="users"></div>

<div align="right"><br><span class="log"></span></div>

</td>

</tr>

</table>

</body>

</html>

Logs.jsp

<%@page contentType="text/html" pageEncoding="utf-8"%>

<%@page import="javax.naming.*, java.util.List, java.util.Date, accessinbuilding.*" %>

<%@page errorPage="err.jsp"%>

<%!

AccessInBuildingSessionRemote ejbRef;

%>

<%

InitialContext ic = new InitialContext();

ejbRef = (AccessInBuildingSessionRemote)ic.lookup("accessinbuilding.AccessInBuildingSessionRemote");

List logs = ejbRef.getLogs( );

int sz = logs.size(), id = 0;

Date date;

String ret = "", descr = "", bgl = "", name = "";

if( sz > 0 ) {

ret = "<br><table width='100%' border='0' cellspacing='0' cellpadding='6'>";

ret += "<tr bgcolor='#68d7f8' class='ubg'>";

ret += "<th width='30' align='right'>№</th>";

ret += "<th width='170' align='left'>Дата</th>";

ret += "<th align='left'>Имя</th>";

ret += "<th align='left'>Лог</th>";

ret += "</tr>";

for(int i=0; i < sz; i++) {

id = ((Log)logs.get(i)).getId();

date = ((Log)logs.get(i)).getDate();

name = ((Log)logs.get(i)).getAssignedAccess().getName();

descr = ((Log)logs.get(i)).getDescr();

bgl = ( (i%2) > 0 ? " bgcolor='#d7e1f2'" : " bgcolor='#eff2f7'" );

ret += "<tr"+bgl+">"+

"<td align='right'>"+ (i+1) +"</td>"+

"<td>"+ date +"</td>"+

"<td>"+ name +"</td>"+

"<td>"+ descr +"</td>"+

"</tr>";

}

ret += "</table>";

}

%>

<%=ret%>

Update_act.jsp

<%@page contentType="text/html" pageEncoding="utf-8"%>

<%@page import="javax.naming.*, accessinbuilding.*" %>

<%@page errorPage="err.jsp"%>

<%!

AccessInBuildingSessionRemote ejbRef;

%>

<%

InitialContext ic = new InitialContext();

ejbRef = (AccessInBuildingSessionRemote)ic.lookup("accessinbuilding.AccessInBuildingSessionRemote");

ejbRef.updateAct( Integer.parseInt(request.getParameter("id")), Integer.parseInt(request.getParameter("act")) );

ejbRef.addLog( Integer.parseInt(request.getParameter("id")), Integer.parseInt(request.getParameter("act")), "" );

%>

done

Users.jsp

<%@page contentType="text/html" pageEncoding="utf-8"%>

<%@page import="javax.naming.*, java.util.List, accessinbuilding.*" %>

<%@page errorPage="err.jsp"%>

<%!

AccessInBuildingSessionRemote ejbRef;

%>

<%

InitialContext ic = new InitialContext();

ejbRef = (AccessInBuildingSessionRemote)ic.lookup("accessinbuilding.AccessInBuildingSessionRemote");

List access = ejbRef.getAllUsers( );

int sz = access.size(), act = 0, id = 0, code = 0;

String ret = "", name = "", stat = "", bgl = "";

if( sz > 0 ) {

ret = "<br><table width='100%' border='0' cellspacing='0' cellpadding='6'>";

ret += "<tr bgcolor='#68d7f8' class='ubg'>";

ret += "<td width='30' align='right'>№</td>";

ret += "<td width='50'>Код</td>";

ret += "<td>ФИО</td>";

ret += "<td width='200' align='center'>Статус</td>";

ret += "</tr>";

for(int i=0; i < sz; i++) {

id = ((Access)access.get(i)).getId();

code = ((Access)access.get(i)).getCode();

name = ((Access)access.get(i)).getName();

act = ((Access)access.get(i)).getAct();

if( act > 0 ) {

bgl = ( (i%2) > 0 ? " bgcolor='#a3eb6f'" : " bgcolor='#f0fbe8'" );

} else {

bgl = ( (i%2) > 0 ? " bgcolor='#d7e1f2'" : " bgcolor='#eff2f7'" );

}

stat = "<div class='radio'>" +

"<input type='radio' name='radio_"+id+"' id='radio_"+id+"_0' value='0'"+ ( act == 0 ? " checked" : "" ) +" /><label class='status' for='radio_"+id+"_0'>нету</label>" +

"<input type='radio' name='radio_"+id+"' id='radio_"+id+"_1' value='1'"+ ( act > 0 ? " checked" : "" ) +" /><label class='status' for='radio_"+id+"_1'>в здании</label>" +

"</div>";

ret += "<tr"+bgl+">"+

"<td align='right'>"+ (i+1) +"</td>"+

"<td>"+ code +"</td>"+

"<td>"+ name +"</td>"+

"<td align='center'>"+ stat +"</td>"+

"</tr>";

}

ret += "</table>";

}

%>

<%=ret%>

Css.css

* { font:14px Arial; }

html, body { margin:0px; padding:0px; }

html { background:#09217d repeat url('http://127.0.0.1:8080/AccessInBuilding-war/img/bg.jpg'); }

body { background:repeat-x top url('http://127.0.0.1:8080/AccessInBuilding-war/img/bg_top.jpg'); min-height: 476px; }

.body {

background: #ffffff;

padding: 20px;

padding-top: 10px;

-webkit-border-bottom-right-radius: 7px;

-webkit-border-bottom-left-radius: 7px;

-moz-border-radius-bottomright: 7px;

-moz-border-radius-bottomleft: 7px;

border-bottom-right-radius: 7px;

border-bottom-left-radius: 7px;

-webkit-box-shadow: 0px 0px 10px 3px rgba(0, 0, 0, 0.7);

box-shadow: 0px 0px 10px 3px rgba(0, 0, 0, 0.7);

}

h1 { font-size: 22px; }

.add_load, .find_load { background: no-repeat center center url('http://127.0.0.1:8080/AccessInBuilding-war/img/loading.gif'); display: none; }

.add_b { position: relative; }

.add_b div {

margin-top: -42px;

width:185px;

padding:5px;

font-size: 11px;

color:#ffffff;

background: #68d7f8 no-repeat 5px 4px url('http://127.0.0.1:8080/AccessInBuilding-war/img/add.png');

margin-bottom: 15px;

border:1px solid #1c8dff;

cursor: pointer;

-webkit-border-radius: 4px;

-moz-border-radius: 4px;

border-radius: 4px;

}

.add_b div:hover, .add_b div.show { background-color:#ed7500; background-position:5px -96px; border-color:#9b4d00; }

.add_form {

display: none;

padding: 15px;

background: #68d7f8;

margin-bottom: 10px;

border-top: 1px solid #ed7500;

border-bottom: 1px solid #ed7500;

-webkit-border-radius: 7px;

-moz-border-radius: 7px;

border-radius: 7px;

}

.add_form.add { background: #a3eb6f; }

.find_form {

display: block;

padding: 10px 26px 10px 8px;

background: url('http://127.0.0.1:8080/AccessInBuilding-war/img/find.png') no-repeat 100% 50% #FC0;

}

.find_err, .find_err * { font-size: 12px; }

.find_err span { border-bottom: 1px dashed; cursor:pointer; }

form sup { color: red; }

input {

padding: 2px;

margin: 2px;

border:1px solid #cfcfcf;

background: #ebf0f6;

-webkit-border-radius: 3px;

-moz-border-radius: 3px;

border-radius: 3px;

}

input[type="text"] {

min-width: 160px;

}

input[type="submit"] {

min-width: 170px;

cursor: pointer;

}

.ubg, .ubg * { color: #ffffff; font-size: 18px; }

.cnt_act { text-align: center; }

.logs { display: none; }

.log { padding-top: 10px; color:#68d7f8; border-bottom: 1px dashed #68d7f8; cursor: pointer; }

.logs td { font-size: 11px; color:#666; }

Js.js

var timer;

jQuery(document).ready(function() {

function showMessage(id,msg) {

jQuery(id).hide().html(msg).show();

setTimeout(function(){ jQuery(id).fadeOut(500); }, 3000);

}

function updateCnt(obj) {

var _this = obj;

jQuery.get("act.jsp",{},function(data) {

data = jQuery.trim( data );

if( data > 0 ) txt = "В здании находится " + data + " человек(а)";

else txt = "В здании никого нет";

jQuery(_this).fadeOut(0).html(txt).fadeIn(1000);

});

}

function updateUsers(obj) {

var _this = obj;

jQuery.get("users.jsp",{},function(data) {

data = jQuery.trim( data );

if( data != "" ) {

jQuery(_this).fadeOut(0).html(data).fadeIn(1000);

jQuery(".radio").buttonset().refresh();

}

});

}

function updateLogs(obj) {

var _this = obj;

jQuery.get("logs.jsp",{},function(data) {

data = jQuery.trim( data );

if( data == "error" ) data = "Ошибка подключения к базе";

jQuery(_this).html(data);

});

}

jQuery(".add_b div").click(function(){

if( jQuery(this).is(".show") ) {

jQuery(this).removeClass("show");

jQuery(".add_form").slideUp().removeClass("add");

} else {

jQuery(this).addClass("show");

jQuery(".add_form").slideDown();

}

});

jQuery(".add").click(function() {

_this = this;

jQuery(".add_load").show();

name = jQuery("#add_name").val();

code = parseInt(jQuery("#add_code").val()) || 0;

jQuery(_this).parent().removeClass("add");

if( name != "" ) {

jQuery.get("add.jsp",{name:name,code:code},function(data) {

if( jQuery.trim( data ) == "done" ) {

showMessage(".add_err","Пользователь добавлен");

jQuery(_this).parent().addClass("add");

updateUsers(jQuery(".users").get(0));

updateLogs(jQuery(".log div").get(0));

} else {

showMessage(".add_err","Ошибка добавления");

}

jQuery(".add_load").hide();

});

} else {

showMessage(".add_err","Ошибка, не заполнено обязательное поле");

jQuery(".add_load").hide();

}

return false;

});

jQuery(".find").click(function() {

_this = this;

jQuery(".find_load").show();

var name = jQuery("#find_name").val();

code = parseInt(jQuery("#find_code").val()) || 0;

if( name != "" || code > 0 ) {

jQuery.get("find.jsp",{name:name,code:code},function(data) {

data = jQuery.trim( data );

if( data == "error" ) {

showMessage(".find_err","Ошибка доступа к базе");

} else if( data > 0 ) {

showMessage(".find_err",name + ", в базе есть");

jQuery(".find_load").hide();

} else if( data == 0 ){

showMessage(".find_err","Нет");

jQuery(".find_load").hide();

};

jQuery(".find_load").hide();

});

} else {

showMessage(".find_err","Ошибка, не заполненно не одно из полей");

jQuery(".find_load").hide();

}

return false;

});

jQuery(".find_err span").click(function() {

jQuery(".find_form #find_name").val(jQuery(this).text());

jQuery(".find").trigger("click");

});

jQuery(".cnt_act").each(function() {

updateCnt(this);

});

jQuery(".users").each(function() {

updateUsers(this);

});

jQuery( '.radio' ).buttonset();

jQuery(".radio span").live("click",function(){

row = jQuery(this).parent().attr("for").split('_');

jQuery.get("update_act.jsp",{id:parseInt(row[1]),act:parseInt(row[2])},function(data) {

updateCnt(jQuery(".cnt_act").get(0));

updateLogs(jQuery(".log div").get(0));

});

});

jQuery(".log").each(function() {

jQuery(this).html("Лог посещаемости<div class='logs'></div>");

});

jQuery(".log").live("click",function(){

div = jQuery('.logs',this);

if( div.is('.show') ) {

div.removeClass("show").slideUp('fast');

} else {

updateLogs(div);

div.addClass("show").slideDown();

}

});

});

Connect.jps

<%@page contentType="application/json" pageEncoding="utf-8"%><%@page import="javax.naming.*, java.util.Date, java.util.List, accessinbuilding.*" %><%@page errorPage="connect_error.jsp"%><%!

AccessInBuildingSessionRemote ejbRef;

%><%

String ret = "{\"error\":\"101\"}";

ejbRef = (AccessInBuildingSessionRemote)session.getAttribute("ejbRef");

if(ejbRef == null) {

InitialContext ic = new InitialContext();

ejbRef = (AccessInBuildingSessionRemote)ic.lookup("accessinbuilding.AccessInBuildingSessionRemote");

session.setAttribute("ejbRef", ejbRef);

}

String getToken = ejbRef.getToken();

if( request.getParameter("token") != null && getToken != "" && getToken.equals(request.getParameter("token")) ) {

String type = request.getParameter("type");

if( "act".equals(type) ) {

ret = "{\"cnt\":\"" + ejbRef.findCountAct() + "\"}";

} else if( "users".equals(type) ) {

List access = ejbRef.getAllUsers( );

int sz = access.size(), act = 0, id = 0, code = 0;

String name = "", stat = "", bgl = "";

if( sz > 0 ) {

ret = "<br><table width='100%' border='0' cellspacing='0' cellpadding='6'>";

ret += "<tr bgcolor='#68d7f8' class='ubg'>";

ret += "<td width='30' align='right'>№</td>";

ret += "<td width='50'>Код</td>";

ret += "<td>ФИО</td>";

ret += "<td width='200' align='center'>Статус</td>";

ret += "</tr>";

for(int i=0; i < sz; i++) {

id = ((Access)access.get(i)).getId();

code = ((Access)access.get(i)).getCode();

name = ((Access)access.get(i)).getName();

act = ((Access)access.get(i)).getAct();

if( act > 0 ) {

bgl = ( (i%2) > 0 ? " bgcolor='#a3eb6f'" : " bgcolor='#f0fbe8'" );

} else {

bgl = ( (i%2) > 0 ? " bgcolor='#d7e1f2'" : " bgcolor='#eff2f7'" );

}

stat = "<div class='radio'>" +

"<input type='radio' name='radio_"+id+"' id='radio_"+id+"_0' value='0'"+ ( act == 0 ? " checked" : "" ) +" /><label class='status' for='radio_"+id+"_0'>нету</label>" +

"<input type='radio' name='radio_"+id+"' id='radio_"+id+"_1' value='1'"+ ( act > 0 ? " checked" : "" ) +" /><label class='status' for='radio_"+id+"_1'>в здании</label>" +

"</div>";

ret += "<tr"+bgl+">"+

"<td align='right'>"+ (i+1) +"</td>"+

"<td>"+ code +"</td>"+

"<td>"+ name +"</td>"+

"<td align='center'>"+ stat +"</td>"+

"</tr>";

}

ret += "</table>";

ret = "{\"users\":\"" + ret + "\"}";

} else

ret = "{\"error\":\"404\"}";

} else if( "logs".equals(type) ) {

List logs = ejbRef.getLogs( );

int sz = logs.size(), id = 0;

Date date;

String descr = "", bgl = "", name = "";

if( sz > 0 ) {

ret = "<br><table width='100%' border='0' cellspacing='0' cellpadding='6'>";

ret += "<tr bgcolor='#68d7f8' class='ubg'>";

ret += "<th width='30' align='right'>№</th>";

ret += "<th width='170' align='left'>Дата</th>";

ret += "<th align='left'>Имя</th>";

ret += "<th align='left'>Лог</th>";

ret += "</tr>";

for(int i=0; i < sz; i++) {

id = ((Log)logs.get(i)).getId();

date = ((Log)logs.get(i)).getDate();

name = ((Log)logs.get(i)).getAssignedAccess().getName();

descr = ((Log)logs.get(i)).getDescr();

bgl = ( (i%2) > 0 ? " bgcolor='#d7e1f2'" : " bgcolor='#eff2f7'" );

ret += "<tr"+bgl+">"+

"<td align='right'>"+ (i+1) +"</td>"+

"<td>"+ date +"</td>"+

"<td>"+ name +"</td>"+

"<td>"+ descr +"</td>"+

"</tr>";

}

ret += "</table>";

ret = "{\"logs\":\"" + ret + "\"}";

} else

ret = "{\"error\":\"505\"}";

} else if( "add".equals(type) ) {

ejbRef.addAccess( request.getParameter("name"), Integer.parseInt(request.getParameter("code")) );

ret = "{\"data\":\"done\"}";

} else if( "find".equals(type) ) {

int findID = ejbRef.findByNameOrCode( request.getParameter("name"), Integer.parseInt(request.getParameter("code")) );

ret = "{\"data\":\""+findID+"\"}";

} else if( "update_act".equals(type) ) {

ejbRef.updateAct( Integer.parseInt(request.getParameter("id")), Integer.parseInt(request.getParameter("act")) );

ejbRef.addLog( Integer.parseInt(request.getParameter("id")), Integer.parseInt(request.getParameter("act")), "" );

ret = "{\"data\":\"done\"}";

} else ret = "{\"error\":\"303\"}";

} else if( request.getParameter("auth_login") != null && request.getParameter("auth_pwd") != null ) {

ejbRef.login(request.getParameter("auth_login"), request.getParameter("auth_pwd"));

getToken = ejbRef.getToken();

if( getToken != "" ) ret = "{\"token\":\"" + getToken + "\"}";

else ret = "{\"error\":\"202\"}";

}

%><%=ret%>

connect_error.jps

<%@page contentType="application/json" pageEncoding="utf-8"%>{"error":"error"}

  • Так же в проекте были использованы JavaScript, библиотеки jQuery v1.8.2 и jQuery UI v1.9.1, CSS стили и CSS jQuery UI v1.9.1.

Index.php

<?

header("Content-Type: text/html; charset=utf-8");

?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>Система учета прохода в здание</title>

<link href="http://127.0.0.1:8080/AccessInBuilding-war/css.css" type="text/css" rel="stylesheet" />

<link href="http://127.0.0.1:8080/AccessInBuilding-war/css/jquery-ui-1.9.1.custom.css" type="text/css" rel="stylesheet">

<script src="http://127.0.0.1:8080/AccessInBuilding-war/jquery-1.8.2.min.js"></script>

<script src="http://127.0.0.1:8080/AccessInBuilding-war/jquery-ui.js"></script>

<script type='text/javascript'>jQuery.noConflict();</script>

<script src="/js.js"></script>

</head>

<body>

<table border="0" cellpadding="0" cellspacing="0" width="700" align="center" class="body">

<tr>

<td>

<h1>Система учета прохода в здание</h1>

<div align="right" class="add_b">

<div align="right">Добавить нового пользователя</div>

</div>

<form action="add.jsp" method="post" enctype="multipart/form-data" class="add_form">

Имя<sup>*</sup>: <input type="text" name="name" id="add_name" value="" />

&nbsp;Код: <input type="text" name="code" id="add_code" value="" />

<input type="submit" value="Добавить пользователя" class="add" /><span class="add_load">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

<div class="add_err"></div>

</form>

<form action="find.jsp" method="post" enctype="multipart/form-data" class="find_form">

Имя<sup>*</sup>: <input type="text" name="name" id="find_name" value="" />

&nbsp;Код: <input type="text" name="code" id="find_code" value="" />

<input type="submit" value="Найти" class="find" /><span class="find_load">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

<div class="find_err">Поиск пользователя, например: <span>Иванов Иван</span> </div>

</form>

<br>

<div class="cnt_act"></div>

<div class="users"></div>

<div align="right"><br><span class="log"></span></div>

</td>

</tr>

</table>

</body>

</html>

Connect.php

<?

include $_SERVER['DOCUMENT_ROOT']."/connect_funcs.php";

$clogin = new ConnectLogin();

header('Content-Type: application/json; charset=utf8');

header('Cache-Control: no-cache');

usleep (100);

if( ($type=$_REQUEST['type']) != "" && $clogin->token ) {

switch($type) {

case "act":

echo $clogin->getData($type);

break;

case "users":

echo $clogin->getData($type);

break;

case "logs":

echo $clogin->getData($type);

break;

case "add":

echo $clogin->getData($type,$opt = array("name"=>$_REQUEST['name'], "code"=>$_REQUEST['code']));

break;

case "find":

echo $clogin->getData($type,$opt = array("name"=>$_REQUEST['name'], "code"=>$_REQUEST['code']));

break;

case "update_act":

echo $clogin->getData($type,$opt = array("id"=>$_REQUEST['id'], "act"=>$_REQUEST['act']));

break;

}

exit;

}

$error = $clogin->error;

if( $error ) echo $error;

else echo '{"error":"101"}';

?>

connect_funcs.php

<?

session_start();

if( !function_exists('json_decode') ) {

include_once $_SERVER['DOCUMENT_ROOT']."/JSON.php";

$json = new Services_JSON();

function json_decode($str) { global $json; return $json->decode($str); }

function json_encode($value) { global $json; return $json->encode($value); }

}

define("TIME_TO_SESSION_LIVE", 3600*24*30); # Время жизни сессии = 3600*24*30 = месяц.

class ConnectLogin {

var $login = "client";

var $pwd = "pwd_client";

var $URL = "http://localhost:8080/AccessInBuilding-war/connect.jsp";

var $token;

var $error;

function ConnectLogin() {

$this->token = $_COOKIE['token'];

if( !$this->token ) {

$this->token = $this->Autorization();

if( $this->token ) setcookie('token', $this->token, time()+TIME_TO_SESSION_LIVE, '/', $_SERVER['HTTP_HOST']);

}

return $this->token;

}

function Autorization() {

$ch = curl_init();//echo "[".$this->URL . "?auth_login=" . $this->login . "&auth_pwd=" . $this->pwd."]";

curl_setopt($ch, CURLOPT_URL, $this->URL . "?auth_login=" . $this->login . "&auth_pwd=" . $this->pwd);

curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)");

curl_setopt($ch, CURLOPT_HEADER, 0);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_TIMEOUT, 30);

curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER['DOCUMENT_ROOT']."/cookies.dat");

curl_setopt($ch, CURLOPT_COOKIEFILE, $_SERVER['DOCUMENT_ROOT']."/cookies.dat");

if( !is_file($_SERVER['DOCUMENT_ROOT']."/cookies.dat") ) file_put_contents($_SERVER['DOCUMENT_ROOT']."/cookies.dat", "");

$result = curl_exec($ch);

curl_close($ch);

$result = json_decode($result);

if( $result->token ) {

return $result->token;

} elseif( $result->error ) {

$this->error = json_encode($result);

}

}

function getData($type="act", $opt=array()) {

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $this->URL . "?token=" . $this->token . "&type=" . $type. (sizeof($opt) > 0 ? "&".http_build_query($opt) : ""));

curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)");

curl_setopt($ch, CURLOPT_HEADER, 0);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_TIMEOUT, 30);

curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER['DOCUMENT_ROOT']."/cookies.dat");

curl_setopt($ch, CURLOPT_COOKIEFILE, $_SERVER['DOCUMENT_ROOT']."/cookies.dat");

if( !is_file($_SERVER['DOCUMENT_ROOT']."/cookies.dat") ) file_put_contents($_SERVER['DOCUMENT_ROOT']."/cookies.dat", "");

$result = curl_exec($ch);

curl_close($ch);

return $result;

}

function disconect() {

$this->token = "";

setcookie('token', "", time()-TIME_TO_SESSION_LIVE, '/', $_SERVER['HTTP_HOST']);

}

}

?>

Js. js

var timer;

jQuery(document).ready(function() {

function showMessage(id,msg) {

jQuery(id).hide().html(msg).show();

setTimeout(function(){ jQuery(id).fadeOut(500); }, 3000);

}

function updateCnt(obj) {

var _this = obj;

jQuery.get("/connect.php",{type:"act"},function(data) {

data = eval(data);

if( data.cnt > 0 ) txt = "В здании находится " + data.cnt + " человек(а)";

else txt = "В здании никого нет";

jQuery(_this).fadeOut(0).html(txt).fadeIn(1000);

});

}

function updateUsers(obj) {

var _this = obj;

jQuery.get("/connect.php",{type:"users"},function(data) {

data = eval(data);

data = data.users;

if( data != "" ) {

jQuery(_this).fadeOut(0).html(data).fadeIn(1000);

jQuery(".radio").buttonset().refresh();

}

});

}

function updateLogs(obj) {

var _this = obj;

jQuery.get("/connect.php",{type:"logs"},function(data) {

data = eval(data);

data = data.logs;

if( data == "error" ) data = "Ошибка подключения к базе";

jQuery(_this).html(data);

});

}

jQuery(".add_b div").click(function(){

if( jQuery(this).is(".show") ) {

jQuery(this).removeClass("show");

jQuery(".add_form").slideUp().removeClass("add");

} else {

jQuery(this).addClass("show");

jQuery(".add_form").slideDown();

}

});

jQuery(".add").click(function() {

_this = this;

jQuery(".add_load").show();

name = jQuery("#add_name").val();

code = parseInt(jQuery("#add_code").val()) || 0;

jQuery(_this).parent().removeClass("add");

if( name != "" ) {

jQuery.get("/connect.php",{type:"add", name:name,code:code},function(data) {

data = eval(data);

data = data.data;

if( jQuery.trim( data ) == "done" ) {

showMessage(".add_err","Пользователь добавлен");

jQuery(_this).parent().addClass("add");

updateUsers(jQuery(".users").get(0));

updateLogs(jQuery(".log div").get(0));

} else {

showMessage(".add_err","Ошибка добавления");

}

jQuery(".add_load").hide();

});

} else {

showMessage(".add_err","Ошибка, не заполнено обязательное поле");

jQuery(".add_load").hide();

}

return false;

});

jQuery(".find").click(function() {

_this = this;

jQuery(".find_load").show();

var name = jQuery("#find_name").val();

code = parseInt(jQuery("#find_code").val()) || 0;

if( name != "" || code > 0 ) {

jQuery.get("/connect.php",{type:"find", name:name,code:code},function(data) {

data = eval(data);

data = data.data;

if( data == "error" ) {

showMessage(".find_err","Ошибка доступа к базе");

} else if( data > 0 ) {

showMessage(".find_err",name + ", в базе есть");

jQuery(".find_load").hide();

} else if( data == 0 ){

showMessage(".find_err","Нет");

jQuery(".find_load").hide();

};

jQuery(".find_load").hide();

});

} else {

showMessage(".find_err","Ошибка, не заполненно не одно из полей");

jQuery(".find_load").hide();

}

return false;

});

jQuery(".find_err span").click(function() {

jQuery(".find_form #find_name").val(jQuery(this).text());

jQuery(".find").trigger("click");

});

jQuery(".cnt_act").each(function() {

updateCnt(this);

});

jQuery(".users").each(function() {

updateUsers(this);

});

jQuery( '.radio' ).buttonset();

jQuery(".radio span").live("click",function(){

row = jQuery(this).parent().attr("for").split('_');

jQuery.get("/connect.php",{type:"update_act", id:parseInt(row[1]),act:parseInt(row[2])},function(data) {

updateCnt(jQuery(".cnt_act").get(0));

updateLogs(jQuery(".log div").get(0));

});

});

jQuery(".log").each(function() {

jQuery(this).html("Лог посещаемости<div class='logs'></div>");

});

jQuery(".log").live("click",function(){

div = jQuery('.logs',this);

if( div.is('.show') ) {

div.removeClass("show").slideUp('fast');

} else {

updateLogs(div);

div.addClass("show").slideDown();

}

});

});

cookies.dat –файл хранящий куку, созданный сервером для взаимосвязи склиен-сервера

# Netscape HTTP Cookie File

# http://curlm.haxx.se/rfc/cookie_spec.html

# This file was generated by libcurl! Edit at your own risk.

localhost FALSE /AccessInBuilding-war FALSE 0 JSESSIONID cf8604e6f1026fb4d5de0b7fc587
Выводы

В процессе выполнения работы, мы ознакомились с принципами построения корпоративных распределенных приложений на основе технологии EJB. Разработали распределенное корпоративное Java-приложение, содержащее серверную часть в форме EJB-модуля и клиентскую часть с web-интерфейсом. Для этого мы спроектировали схему БД и реализовали хранение данных в СУБД Java DB с помощью технологии Java EE 5 Persistence. Дополнительно было изучено взаимодействие между 2-я приложениями, реализованными на разных языках программирования: java – серверная часть и много клиентов на php, которые взаимодействуют с помощью JSON за

Наши рекомендации