Ну вот мы и добрались до конечной цели нашего ознакомления с технологией EJB. Несомненно мы не рассмотрели довольно много для этой технологии, но автор ставил себе цель ознакомить, дать некую ниточку, за которую вы сами сможете расскручивать эту технолгию.
Сделаю только одно замечание – для быстрого обновления изменений в коде я советую использовать правую кнопку мыши – кликаете наStudentsApp и выбираете пункт «Undeploy and Deploy»
Чтобы не откладывать в долгий ящки, начнем с текстов. После каждого файла я буду комментировать особо важные участки кода. И начнем мы с файлов, которые нам сгенерил NetBeans по структуре наших таблиц – Groups.java и Students.java
Groups.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
package students.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; @Entity @Table(name = "groups") @NamedQueries({ @NamedQuery(name = "Groups.findByGroupId", query = "SELECT g FROM Groups g WHERE g.groupId = :groupId"), @NamedQuery(name = "Groups.findByGroupName", query = "SELECT g FROM Groups g WHERE g.groupName = :groupName"), @NamedQuery(name = "Groups.findByCurator", query = "SELECT g FROM Groups g WHERE g.curator = :curator"), @NamedQuery(name = "Groups.findBySpeciality", query = "SELECT g FROM Groups g WHERE g.speciality = :speciality") }) public class Groups implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "group_id", nullable = false) private Integer groupId; @Column(name = "groupName", nullable = false) private String groupName; @Column(name = "curator", nullable = false) private String curator; @Column(name = "speciality", nullable = false) private String speciality; public Groups() { } public Groups(Integer groupId) { this.groupId = groupId; } public Groups(Integer groupId, String groupName, String curator, String speciality) { this.groupId = groupId; this.groupName = groupName; this.curator = curator; this.speciality = speciality; } public Integer getGroupId() { return groupId; } public void setGroupId(Integer groupId) { this.groupId = groupId; } public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } public String getCurator() { return curator; } public void setCurator(String curator) { this.curator = curator; } public String getSpeciality() { return speciality; } public void setSpeciality(String speciality) { this.speciality = speciality; } @Override public int hashCode() { int hash = 0; hash += (groupId != null ? groupId.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Groups)) { return false; } Groups other = (Groups) object; if ((this.groupId == null && other.groupId != null) || (this.groupId != null && !this.groupId.equals(other.groupId))) { return false; } return true; } @Override public String toString() { return "students.entity.Groups[groupId=" + groupId + "]"; } } |
В данном файле все самое интересное находится в самом начале – это секция, где очень много надписей @NamedQuery. Вообще-то они генерятся в одну строку, но я для удобства восприятия разделил их на несколько. Это можно сделать без каких-либо проблем. Мы увидим некоторые их @NamedQuery чуть ниже. А пока важно уяснить следующее – это способ, который позволяет нам писать на EJB-QL.EJB-QL – это некоторый аналог SQL, только для EJB. Если внимательно посмотреть на значения строк query, то можно увидеть, что мы в какой-то мере обращаемся к объектам и их полям. Ведь на самом деле в таблице groups нет поля groupId. Там есть group_id. Но если посмотреть чуть ниже, то можно увидеть дополнительную аннотацию, которая «оборачивает» члены нашего класса. И это позволяет нам так красиво делать SELECT. Кроме того можно увидеть именованные параметры – они выделяются тем, что перед ними ставится двоеточие. Их хорошо должно быть видно.
Думаю, что поля, которые описаны возле @Column (name и nullable) достаточно очевидны. Также можно увидеть аннотацию @Id возле поля group_id. Прошу вас отметить, что это не элементарный тип данных int, а полноценный класс Integer. Т.е. он может быть равен null. Почему это важно мы увидим несколько позже. А пока запомните, что даже ID может быть NULL.
Students.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
package students.entity; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity @Table(name = "students") @NamedQueries({ @NamedQuery(name = "Students.findByStudentId", query = "SELECT s FROM Students s WHERE s.studentId = :studentId"), @NamedQuery(name = "Students.findByFirstName", query = "SELECT s FROM Students s WHERE s.firstName = :firstName"), @NamedQuery(name = "Students.findBySurName", query = "SELECT s FROM Students s WHERE s.surName = :surName"), @NamedQuery(name = "Students.findByPatronymic", query = "SELECT s FROM Students s WHERE s.patronymic = :patronymic"), @NamedQuery(name = "Students.findByDateOfBirth", query = "SELECT s FROM Students s WHERE s.dateOfBirth = :dateOfBirth"), @NamedQuery(name = "Students.findBySex", query = "SELECT s FROM Students s WHERE s.sex = :sex"), @NamedQuery(name = "Students.findByGroupId", query = "SELECT s FROM Students s WHERE s.groupId = :groupId"), @NamedQuery(name = "Students.findByEducationYear", query = "SELECT s FROM Students s WHERE s.educationYear = :educationYear"), @NamedQuery(name = "Students.findByGroupAndYear", query = "SELECT s FROM Students s WHERE s.groupId = :groupId AND s.educationYear=:educationYear"), @NamedQuery(name = "Students.updateGroupAndYear", query = "UPDATE Students s SET s.groupId=:groupId, s.educationYear=:educationYear WHERE s.groupId = :oldGroupId AND s.educationYear=:oldEducationYear") }) public class Students implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "student_id", nullable = false) private Integer studentId; @Column(name = "firstName", nullable = false) private String firstName; @Column(name = "surName", nullable = false) private String surName; @Column(name = "patronymic", nullable = false) private String patronymic; @Column(name = "dateOfBirth", nullable = false) @Temporal(TemporalType.DATE) private Date dateOfBirth; @Column(name = "sex") private Character sex = 'М'; @Column(name = "group_id", nullable = false) private int groupId; @Column(name = "educationYear", nullable = false) private int educationYear; public Students() { } public Students(Integer studentId) { this.studentId = studentId; } public Students(Integer studentId, String firstName, String surName, String patronymic, Date dateOfBirth, int groupId, int educationYear) { this.studentId = studentId; this.firstName = firstName; this.surName = surName; this.patronymic = patronymic; this.dateOfBirth = dateOfBirth; this.groupId = groupId; this.educationYear = educationYear; } public Integer getStudentId() { return studentId; } public void setStudentId(Integer studentId) { this.studentId = studentId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getSurName() { return surName; } public void setSurName(String surName) { this.surName = surName; } public String getPatronymic() { return patronymic; } public void setPatronymic(String patronymic) { this.patronymic = patronymic; } public Date getDateOfBirth() { return dateOfBirth; } public void setDateOfBirth(Date dateOfBirth) { this.dateOfBirth = dateOfBirth; } public Character getSex() { return sex; } public void setSex(Character sex) { this.sex = sex; } public int getGroupId() { return groupId; } public void setGroupId(int groupId) { this.groupId = groupId; } public int getEducationYear() { return educationYear; } public void setEducationYear(int educationYear) { this.educationYear = educationYear; } @Override public int hashCode() { int hash = 0; hash += (studentId != null ? studentId.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Students)) { return false; } Students other = (Students) object; if ((this.studentId == null && other.studentId != null) || (this.studentId != null && !this.studentId.equals(other.studentId))) { return false; } return true; } @Override public String toString() { return "students.entity.Students[studentId=" + studentId + "]"; } } |
Этот файл уже выглядит знакомым. Единственное, что мы в нем поменяли – это сделали несколько строк для именованных запросов (NamedQuery) и ДОБАВИЛИ свои – два последних — «Students.findByGroupAndYear» и «Students.updateGroupAndYear». Они нам просто понадобятся, потому и добавили.
Первый запрос отличатеся от стандартно сгенеренных тем, что он использует не один дополнительный параметр, а два. Второй запрос еще интереснее – он не возвращает данные, он изменяет их. Но в остальном ничем особым не выделяется.
Что еще хотелось бы отметить – все эти страшные аннотации интересны именно Application Server’у. Для тех, кто не использует их это самые обычные классы с обычными полями. Их можно скомпилировать и использовать где угодно. Но как только они попадают кAppServer’у, то у того сразу появляется информаци о том, к какой таблице «привязан» данный класс. И теперь как только происходит какая-либо работа с базой данных наш класс используется как хранилище для данных из строки таблицы. Т.е. если мы вытащим много записей из таблицы students, то все они лягут в список, элементами которого будут объекты класса Students. И это мы увидим прямо сейчас. Настало время обратить взор к одному из важнейших наших классов – ManagementSystemBean и его интерфейсуManagementSystemLocal.
ManagementSystemLocal.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package students.logic; import java.util.List; import javax.ejb.Local; import students.entity.Groups; import students.entity.Students; @Local public interface ManagementSystemLocal { // Получить данные об одном студенте Students getStudents(int studentId); // Получить список всех групп List<Groups> getGroupsList(); // Получить список студентов для конкретной группы и конкретного года обучения List<Students> getStudentsFromGroup(int groupId, int year); // Переместить студентов из одной группы в другую. Причем мы учитываем и год обучения void moveStudentsToGroup(int groupId, int year, int newGroupId, int newYear); // Добавить нового студента void insertStudents(Students st); // Изменить данные о студенте void updateStudents(Students st); // Удалить студента void deleteStudents(int studentsId); } |
Здесь в общем-то ничего особенного нет – описаны необходимые нам методы. И интерфейс их содержит. Единственное, что вам рекомендуется сделать – это прочитать комментарии для чего каждый метод предназначен.
А вот реализация у нас займет несколько больше внимания и сил. Итак:
ManagementSystemBean.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
package students.logic; import java.sql.Ref; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import students.entity.Groups; import students.entity.Students; @Stateless (name="ManagementSystem") public class ManagementSystemBean implements ManagementSystemLocal { @PersistenceContext private EntityManager em; public void persist(Object object) { em.persist(object); } public Students getStudents(int studentId) { return em.find(Students.class, studentId); } public List<Groups> getGroupsList() { Query q = em.createQuery("SELECT g FROM Groups g"); List<Groups> l= q.getResultList(); return l; } public List<Students> getStudentsFromGroup(int groupId, int year) { Query q = em.createNamedQuery("Students.findByGroupAndYear"); q.setParameter("groupId", groupId); q.setParameter("educationYear", year); List<Students> l= q.getResultList(); return l; } public void moveStudentsToGroup(int groupId, int year, int newGroupId, int newYear) { Query q = em.createNamedQuery("Students.updateGroupAndYear"); q.setParameter("groupId", newGroupId); q.setParameter("educationYear", newYear); q.setParameter("oldGroupId", groupId); q.setParameter("oldEducationYear", year); q.executeUpdate(); } public void insertStudents(Students st) { em.persist(st); } public void updateStudents(Students st) { Students sOld = em.find(Students.class, st.getStudentId()); sOld.setFirstName(st.getFirstName()); sOld.setSurName(st.getSurName()); sOld.setPatronymic(st.getPatronymic()); sOld.setDateOfBirth(st.getDateOfBirth()); sOld.setGroupId(st.getGroupId()); sOld.setSex(st.getSex()); sOld.setEducationYear(st.getEducationYear()); em.persist(sOld); } public void deleteStudents(int studentsId) { Students sOld = em.find(Students.class, studentsId); em.remove(sOld); } } |
Вот здесь нам придется посмотреть на несколько методов.
getGroupsList() – этот метод получает список групп. Обратите внимание вот на что – здесь мы используем EJB-QL «напрямую». Т.е. создаем запрос и выполняем его. В остальных случаях используются именованные запросы.
getStudentsFromGroup(int groupId, int year) – здесь мы используем именованный запрос (который мы создали). В принципе каких-то сложностей в коде я не вижу – все достаточно очевидно.
moveStudentsToGroup(int groupId, int year, int newGroupId, int newYear) – в этом методе есть только один тонкий момент – здесь мы используем несколько другой вызов – executeUpdate. В других случаях мы использовали getResultList.
И вот тут мы подходим к методам, которые содержат некую хитринку.
insertStudents(Students st) – этот метод будет прекрасно работать только в одном случае. ЕСЛИ объект не имеет установленного поля studentsId. Помните я обращал ваше внимание на то, что теперь ID уже не элементарный тип, а реальный класс. Так вот – если он равен NULL, тогда будет производится его вставка в таблицу. Если же у него будет установлен ID – вставки не будет. Вернее будет, но только один раз. Это очень важный момент.
Когда я первый раз вставляю нового студента с установленным ID, то происходит следующее – PersistenceManager проверяет – нет ли студента с таким значением ID. Если нет – то он его вставляет. Если же такой ID был зарегистрирован, то данные студента пытаются обновить. Что очень важно – PersistenceManager не делает обновления ID при вставке у объекта, который мы вставляли. Что еще неприятнее – если вы вставили нового студента с установленным ID (ну так вышло), то если вы опять попытаетесь это сделать, то ничего не выйдет. PersistenceManager запоминает, что уже такой ID был, и он попытается проапдейтить студента. И тут мы обратим наш взор на метод updateStudents.
updateStudents(Students st) – посмотрите на код этого метода. В первой строке я должен вытащить студента по ID, изменить его поля на новые значения (которые я передал в аргументе) и снова сохранить. Т.е PersistenceManager должен иметь «привязанный» (attached) к базе объект. Я себе почему-то сразу представил, что мы «за резиночку» вытаскиваем структуру, заполняем ее, а потом отпускаем. ИPersistenceManager с уже новыми значениями притягивает «за резиночку» измененный объект и записывает его в базу. Может у вас появится другая ассоциация – но вот у меня такая получилась. А просто заполненный объект – он просто заполненный объект, который не имеет связи с базой и потому при попытке его сохранения вам будет выдано предупреждение. Попробуйте в методе закомментировать все строки и вставьте вот такую:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void updateStudents(Students st) { // Students sOld = em.find(Students.class, st.getStudentId()); // sOld.setFirstName(st.getFirstName()); // sOld.setSurName(st.getSurName()); // sOld.setPatronymic(st.getPatronymic()); // sOld.setDateOfBirth(st.getDateOfBirth()); // sOld.setGroupId(st.getGroupId()); // sOld.setSex(st.getSex()); // sOld.setEducationYear(st.getEducationYear()); em.persist(st); } |
Посмотрите, что получится.
deleteStudents(int studentsId) – здесь та же самая иде «резиночки». Вытаскиваем «привязанный» объект и удаляем.
Файлы сервлетов я комментировать не буду – они просто очень похожи на те, что мы делали в Часть 9 — Простое WEB-приложение. Просто приведу текст. Не забудьте – они должны находится в проекте StudentsApp-war !
MainFrameServlet.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
package students.web; import java.io.IOException; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; import javax.ejb.EJB; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import students.entity.Students; import students.entity.Groups; import students.logic.ManagementSystemLocal; import students.web.forms.MainFrameForm; import students.web.forms.StudentForm; public class MainFrameServlet extends HttpServlet { @EJB(name = "ManagementSystem") private ManagementSystemLocal ms; protected void processRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int answer = 0; answer = checkAction(req); if (answer == 1) { Students s = new Students(); s.setStudentId(0); s.setDateOfBirth(new Date()); s.setEducationYear(Calendar.getInstance().get(Calendar.YEAR)); List<Groups> groups = ms.getGroupsList(); StudentForm sForm = new StudentForm(); sForm.initFromStudent(s); sForm.setGroups(groups); req.setAttribute("student", sForm); getServletContext().getRequestDispatcher("/StudentFrame.jsp").forward(req, resp); return; } if (answer == 2) { if (req.getParameter("studentId") != null) { int stId = Integer.parseInt(req.getParameter("studentId")); Students s = ms.getStudents(stId); List<Groups> groups = ms.getGroupsList(); StudentForm sForm = new StudentForm(); sForm.initFromStudent(s); sForm.setGroups(groups); req.setAttribute("student", sForm); getServletContext().getRequestDispatcher("/StudentFrame.jsp").forward(req, resp); return; } } String gs = req.getParameter("groupId"); String ys = req.getParameter("year"); if (answer == 3) { String newGs = req.getParameter("newGroupId"); String newYs = req.getParameter("newYear"); ms.moveStudentsToGroup(Integer.parseInt(gs), Integer.parseInt(ys), Integer.parseInt(newGs), Integer.parseInt(newYs)); gs = newGs; ys = newYs; } int groupId = -1; if (gs != null) { groupId = Integer.parseInt(gs); } int year = Calendar.getInstance().get(Calendar.YEAR); if (ys != null) { year = Integer.parseInt(ys); } MainFrameForm form = new MainFrameForm(); List<Groups> groups = ms.getGroupsList(); if (groupId == -1) { Iterator<Groups> i = groups.iterator(); groupId = i.next().getGroupId(); } List<Students> students = ms.getStudentsFromGroup(groupId, year); form.setGroupId(groupId); form.setYear(year); form.setGroups(groups); form.setStudents(students); req.setAttribute("form", form); getServletContext().getRequestDispatcher("/MainFrame.jsp").forward(req, resp); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { processRequest(req, resp); } public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { processRequest(req, resp); } private int checkAction(HttpServletRequest req) { if (req.getParameter("Add") != null) { return 1; } if (req.getParameter("Edit") != null) { return 2; } if (req.getParameter("MoveGroup") != null) { return 3; } if (req.getParameter("Delete") != null) { if (req.getParameter("studentId") != null) { ms.deleteStudents(Integer.parseInt(req.getParameter("studentId"))); } return 0; } return 0; } } |
StudetnFrameServlet.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
package students.web; import java.io.IOException; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.text.ParseException; import java.util.Calendar; import java.util.Iterator; import java.util.List; import javax.ejb.EJB; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import students.entity.Groups; import students.logic.ManagementSystemLocal; import students.entity.Students; import students.web.forms.MainFrameForm; public class StudentFrameServlet extends HttpServlet { @EJB(name = "ManagementSystem") private ManagementSystemLocal ms; private static final SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); protected void processRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String sId = req.getParameter("studentId"); if (sId != null && req.getParameter("OK") != null) { try { if (Integer.parseInt(sId) > 0) { updateStudent(req); } else { insertStudent(req); } } catch (SQLException sql_e) { sql_e.printStackTrace(); throw new IOException(sql_e.getMessage()); } catch (ParseException p_e) { throw new IOException(p_e.getMessage()); } } String gs = req.getParameter("groupId"); String ys = req.getParameter("educationYear"); int groupId = -1; if (gs != null) { groupId = Integer.parseInt(gs); } int year = Calendar.getInstance().get(Calendar.YEAR); if (ys != null) { year = Integer.parseInt(ys); } MainFrameForm form = new MainFrameForm(); List<Groups> groups = ms.getGroupsList(); if (groupId == -1) { Iterator<Groups> i = groups.iterator(); groupId = i.next().getGroupId(); } List<Students> students = ms.getStudentsFromGroup(groupId, year); form.setGroupId(groupId); form.setYear(year); form.setGroups(groups); form.setStudents(students); req.setAttribute("form", form); getServletContext().getRequestDispatcher("/MainFrame.jsp").forward(req, resp); } @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { processRequest(req, resp); } @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { processRequest(req, resp); } private void updateStudent(HttpServletRequest req) throws SQLException, ParseException { Students s = prepareStudent(req); ms.updateStudents(s); } private void insertStudent(HttpServletRequest req) throws SQLException, ParseException { Students s = prepareStudent(req); ms.insertStudents(s); } private Students prepareStudent(HttpServletRequest req) throws ParseException { Students s = new Students(); // Здесь важно отметить, что для ID нельзя задавать ничего если надо добавлять // ID должен быть равен NULL if(Integer.parseInt(req.getParameter("studentId"))>0) { s.setStudentId(Integer.parseInt(req.getParameter("studentId"))); } s.setFirstName(req.getParameter("firstName").trim()); s.setSurName(req.getParameter("surName").trim()); s.setPatronymic(req.getParameter("patronymic").trim()); s.setDateOfBirth(sdf.parse(req.getParameter("dateOfBirth").trim())); if (req.getParameter("sex").equals("0")) { s.setSex('М'); } else { s.setSex('Ж'); } s.setGroupId(Integer.parseInt(req.getParameter("groupId").trim())); s.setEducationYear(Integer.parseInt(req.getParameter("educationYear").trim())); return s; } } |
MainFrameForm.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
package students.web.forms; import java.util.Collection; public class MainFrameForm { private int year; private int groupId; private Collection groups; private Collection students; public void setYear(int year) { this.year = year; } public int getYear() { return year; } public void setGroupId(int groupId) { this.groupId = groupId; } public int getGroupId() { return groupId; } public void setGroups(Collection groups) { this.groups = groups; } public Collection getGroups() { return groups; } public void setStudents(Collection students) { this.students = students; } public Collection getStudents() { return students; } } |
StudetnForm.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
package students.web.forms; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.List; import students.entity.Groups; import students.entity.Students; public class StudentForm { private static SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); private int studentId; private String firstName; private String surName; private String patronymic; private String dateOfBirth; private int sex; private int groupId; private int educationYear; private List<Groups> groups; public void initFromStudent(Students st) { this.studentId = st.getStudentId(); this.firstName = st.getFirstName(); this.surName = st.getSurName(); this.patronymic = st.getPatronymic(); this.dateOfBirth = sdf.format(st.getDateOfBirth()); if(st.getSex().equals(new Character('М'))) { this.sex = 0; } else { this.sex = 1; } this.groupId = st.getGroupId(); this.educationYear = st.getEducationYear(); } public String getDateOfBirth() { return dateOfBirth; } public void setDateOfBirth(String dateOfBirth) { this.dateOfBirth = dateOfBirth; } public int getEducationYear() { return educationYear; } public void setEducationYear(int educationYear) { this.educationYear = educationYear; } public int getGroupId() { return groupId; } public void setGroupId(int groupId) { this.groupId = groupId; } public int getStudentId() { return studentId; } public void setStudentId(int studentId) { this.studentId = studentId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getPatronymic() { return patronymic; } public void setPatronymic(String patronymic) { this.patronymic = patronymic; } public String getSurName() { return surName; } public void setSurName(String surName) { this.surName = surName; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } public void setGroups(List<Groups> groups) { this.groups = groups; } public Collection getGroups() { return groups; } } |
Ну и JSP странички – вот такие.
MainFrame.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
<%@ page contentType="text/html; charset=windows-1251" %> <%@ taglib uri="/WEB-INF/tld/c.tld" prefix="c" %> <html> <head> <title>Список студентов</title> </head> <body> <form action='<c:url value="/main"/>' method="POST"> <table> <tr> <td>Год:<input type="text" name="year" value="${form.year}"/><br/></td> <td>Список групп: <select name="groupId"> <c:forEach var="group" items="${form.groups}"> <c:choose> <c:when test="${group.groupId==form.groupId}"> <option value="${group.groupId}" selected><c:out value="${group.groupName}"/></option> </c:when> <c:otherwise> <option value="${group.groupId}"><c:out value="${group.groupName}"/></option> </c:otherwise> </c:choose> </c:forEach> </select> </td> <td><input type="submit" name="getList" value="Обновить"/></td> </tr> </table> <p/><b>Список студентов для выбранных параметров:<b><br/> <table> <tr> <th> </th> <th>Фамилия</th> <th>Имя</th> <th>Отчество</th> </tr> <c:forEach var="student" items="${form.students}"> <tr> <td><input type="radio" name="studentId" value="${student.studentId}"></td> <td><c:out value="${student.surName}"/></td> <td><c:out value="${student.firstName}"/></td> <td><c:out value="${student.patronymic}"/></td> </tr> </c:forEach> </table> <table> <tr> <td><input type="submit" value="Add" name="Add"/></td> <td><input type="submit" value="Edit" name="Edit"/></td> <td><input type="submit" value="Delete" name="Delete"/></td> </tr> </table> <p/><b>Переместить студентов в группу<b><br/> <table> <tr> <td>Год:<input type="text" name="newYear" value="${form.year}"/><br/></td> <td>Список групп: <select name="newGroupId"> <c:forEach var="group" items="${form.groups}"> <option value="${group.groupId}"><c:out value="${group.groupName}"/></option> </c:forEach> </select> </td> <td><input type="submit" name="MoveGroup" value="Переместить"/></td> </tr> </table> </form> </body> </html> |
StudentFrame.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
<%@ page contentType="text/html; charset=windows-1251" %> <%@ taglib uri="/WEB-INF/tld/c.tld" prefix="c" %> <html> <head> <title>Список студентов</title> </head> <body> <form action='<c:url value="/edit"/>' method="POST"> <input type="hidden" name="studentId" value="${student.studentId}"/> <table> <tr> <td>Фамилия:</td><td><input type="text" name="surName" value="${student.surName}"/></td> </tr> <tr> <td>Имя:</td><td><input type="text" name="firstName" value="${student.firstName}"/></td> </tr> <tr> <td>Отчество:</td><td><input type="text" name="patronymic" value="${student.patronymic}"/></td> </tr> <tr> <td>Дата рождения:</td><td><input type="text" name="dateOfBirth" value="${student.dateOfBirth}"/></td> </tr> <tr> <td>Пол:</td> <td> <c:choose> <c:when test="${student.sex==0}"> <input type="radio" name="sex" value="0" checked>М</input> <input type="radio" name="sex" value="1">Ж</input> </c:when> <c:otherwise> <input type="radio" name="sex" value="0">М</input> <input type="radio" name="sex" value="1" checked>Ж</input> </c:otherwise> </c:choose> </td> </tr> <tr> <td>Группа:</td> <td> <select name="groupId"> <c:forEach var="group" items="${student.groups}"> <c:choose> <c:when test="${group.groupId==student.groupId}"> <option value="${group.groupId}" selected><c:out value="${group.groupName}"/></option> </c:when> <c:otherwise> <option value="${group.groupId}"><c:out value="${group.groupName}"/></option> </c:otherwise> </c:choose> </c:forEach> </select> </td> </tr> <tr> <td>Год обучения:</td><td><input type="text" name="educationYear" value="${student.educationYear}"/></td> </tr> </table> <table> <tr> <td><input type="submit" value="OK" name="OK"/></td> <td><input type="submit" value="Cancel" name="Cancel"/></td> </tr> </table> </form> </body> </html> |
Также я привожу файл web.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>MainFrameServlet</servlet-name> <servlet-class>students.web.MainFrameServlet</servlet-class> </servlet> <servlet> <servlet-name>StudentFrameServlet</servlet-name> <servlet-class>students.web.StudentFrameServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MainFrameServlet</servlet-name> <url-pattern>/main</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>StudentFrameServlet</servlet-name> <url-pattern>/edit</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>main</welcome-file> </welcome-file-list> </web-app> |
Обратите внимание на то, что в качестве welcome-file-list> у нас отмечен наш сервлет MainFrameServlet. Т.е. когда вы запустите проект он будет отображаться сразу же. Мелочь, а приятно.
ЧТО ЕЩЕ ОЧЕНЬ ВАЖНО !!!
Вам надо скопировать файлы из директории tld (надеюсь вы не забыли – это наши тэги для управления контентом в JSP.
Ваш проект находится где-то по такому пути
C:\Documents and Settings\<user>\My Documents\NetBeansProjects\StudentsApp\StudentsApp-war\web
Вот здесь и надо копировать наш каталог tld – в WEB-INF. NetBeans «подхватит» добавленные файлы.