Класс Main сервлета
Класс Main сервлета, в котором обрабатывается информация, введенная пользователем на главной HTML-странице (main.html), показан в листинге 6.45. Центральной точкой входа в этот класс сервлета является метод doGet. После задания исходных значений некоторых переменных этот метод пытается получить объект Session из запроса. Если этого объекта еще не существует, нужно создать новый объект Session. Затем создается новый объект Catalog на основе файла catalog.xml. Этот объект Catalog присоединяется к сеансу с помощью метода setAttribute. Если же обнаружен существующий объект Session, объект catalog можно получить как атрибут уже существующего сеанса.
Листинг 6.45. Начало кода класса Main и метод doGet (Main.java)
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import com.XmlEcomBook.Chap06.*;
public class Main extends HttpServlet { static private final String FILE_NAME = "catalog.xml";
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { // Access the output stream. PrintWriter out = res.getWriter(); res.setContentType("text/html"); HttpSession session = req.getSession(false); Catalog catalog = null;
if( session == null ) { //There is no session, create a new one session = req.getSession( true ); catalog = new Catalog( FILE_NAME ); session.setAttribute( "catalog", catalog ); } else { catalog = (Catalog)session.getAttribute( "catalog" ); }
После этого метод doGet переходит к выполнению следующей задачи — извлечению всех значений, которые пользователь ввел в форму HTML, как показано в верхней части листинга 6.46. Эти значения извлекаются из объекта HttpServl etRequest с помощью метода getParameter. Затем эти значения проверяются на наличие ошибок. В первую очередь, если выбрана одна из основных операций (добавление, удаление или редактирование товара), проверяется, указан ли идентификатор товара. Затем из каталога извлекается элемент (товар) с этим идентификатором. Если выполняется операция по удалению или редактированию элемента, требуется проверить, что этот элемент действительно присутствует в каталоге, иначе выдается сообщение об ошибке. Если выполняется операция по добавлению товара в каталог, то нужно проверить, нет ли уже в каталоге товара с таким идентификатором, поскольку каждый идентификатор должен быть уникален. Также при добавлении товара в каталог нужно убедиться, что указанная для товара серия действительно присутствует в каталоге. Нужно проверить состояние булевой переменной error (признак ошибки); если ее значение установлено равным true, то нужно отобразить страницу с сообщением об ошибке. Метод, который отображает эту страницу, будет рассмотрен далее в этом разделе.
Листинг 6.46. Проверка ошибок во введенных параметрах (Main.java)
String operation = req.getParameter("operation"); String productID = req.getParameter("productid"); String productLine = req.getParameter("productline");
boolean error = false; String errorMsg = "Unkown Error"; if( operation.equals( "delete" ) || operation.equals( "edit" ) || operation.equals( "add" ) ) { if( productID == null || productID.equals("") ) { error = true; errorMsg = "You must select a product ID with the " + operation + " operation."; } else { Product product = catalog.getProduct( productID ); if( operation.equals( "edit" ) || operation.equals( "delete" ) ) { if( product == null ) { error = true; errorMsg = "Invalid product ID:" + productID; } } if( operation.equals( "add" ) ) { if( product != null ) { error = true; errorMsg = "Cannot add, product id " + productID + " already exists."; } ProductLine pl = catalog.getProductLine( productLine ); if( pl == null ) { error = true; errorMsg = "No product line " + productLine + " exists."; } } } }
if( error ) { outputPage( out, "Error", errorMsg ); return; }
После того как вы убедились, что все параметры введены правильно, можно приступить к их фактической обработке, как показано в листинге 6.47. У вас имеется последовательность инструкций if для определения, какие действия следует выполнять в том или ином случае. Для добавления и редактирования данных о товаре используется одна и та же JSP-страница. Чтобы вызвать из сервлета JSP- страницу, вызывается метод getRequestDi spatcher объекта класса ServletContext и задается URL-адрес относительно корневой папки сервлета (например, Edit.jsp). После получения объекта класса RequestDi spatcher вызывается его метод forward, которому в качестве параметров передаются объекты классов HttpServletRequest и HttpServl etResponse, то есть текущие запрос (req) и ответ (res). Это позволяет передать JSP-странице все текущие параметры. Операция по удалению товара аналогичным образом вызывает другую JSP-страницу. Операция по отмене всех изменений выполняется непосредственно в методе doGet. Для этого просто вызывается метод invalidate объекта session. Этот метод делает текущий сеанс недействительным и прекращает все связи с объектами. Последняя команда, которая сохраняет все сделанные в течение сеанса изменения, также выполняется непосредственно в методе doGet. Здесь создается новый объект класса XMLWriter, использующий файл catalog.xml. Туда вписываются необходимые строки, содержащие объявление XML и объявление типа документа. Затем используется метод toXML объекта catal og для того, чтобы записать данные в формате XML в этот файл.
Листинг 6.47. Обработка различных операций (Main.java)
if( operation.equals( "add" ) || operation.equals( "edit" ) ) { getServletContext().getRequestDispatcher ("/Edit.jsp").forward(req, res); } if( operation.equals( "delete" ) ) { getServletContext(). getRequestDispatcher("/Delete.jsp").forward(req, res); } if( operation.equals( "refresh" ) ) { session.invalidate(); outputPage( out, "Session Cancelled", " The session has been canelled" ); return; } if( operation.equals( "save" ) ) { try { FileOutputStream outFile = new FileOutputStream( FILE_NAME ); XMLWriter writer = new XMLWriter( outFile ); writer.writeln( "<?xml version='1.0' standalone='no' ?>" ); writer.writeln( "<!DOCTYPE catalog SYSTEM 'catalog.dtd'>" ); catalog.toXML( writer ); } catch( IOException e ) { outputPage( out, "Error", "I/O Exception writing XML file" ); return; } outputPage( out, "Changes saved", "The changes have been saved" ); } }
В сервлете Main имеется метод для создания и отображения простой HTML- страницы. Этот метод приведен в листинге 6.48. Ему передается объект PrintWriter, заголовок и текст, который будет отображен на странице. На этой странице также будет расположена ссылка на главную HTML-страницу.
Листинг 6.48. Отображение страницы (Main.java)
private void outputPage( PrintWriter out, String title, String text ) { out.println("<html><head><title>" + title ); out.println("</title></head><body>"); out.println("<p>" + text + "</p>"); out.println("<a href='/main.html'>Return to main page.</a>"); out.println("</body></html>"); } }