· 9 years ago · Aug 10, 2017, 12:42 PM
1package net.coderodde.web.db.fun.controllers;
2
3import java.io.IOException;
4import java.io.PrintWriter;
5import javax.servlet.ServletException;
6import javax.servlet.annotation.WebServlet;
7import javax.servlet.http.HttpServlet;
8import javax.servlet.http.HttpServletRequest;
9import javax.servlet.http.HttpServletResponse;
10import net.coderodde.web.db.fun.model.FunnyPerson;
11
12/**
13 * This controller is responsible for creating new persons.
14 *
15 * @author Rodion "rodde" Efremov
16 * @version 1.6 (Aug 8, 2017)
17 */
18@WebServlet(name = "AddPersonController", urlPatterns = {"/add_person"})
19public class AddPersonController extends HttpServlet {
20
21 /**
22 * The SQL command for inserting a person.
23 */
24 private static final String INSERT_PERSON_SQL =
25 "INSERT INTO funny_persons (first_name, last_name, email) VALUES " +
26 "(?, ?, ?);";
27
28 /**
29 * Handles the HTTP <code>GET</code> method.
30 *
31 * @param request the servlet request.
32 * @param response the servlet response.
33 * @throws ServletException if a servlet-specific error occurs.
34 * @throws IOException if an I/O error occurs.
35 */
36 @Override
37 protected void doGet(HttpServletRequest request, HttpServletResponse response)
38 throws ServletException, IOException {
39 response.setContentType("text/html;charset=UTF-8");
40 try (PrintWriter out = response.getWriter()) {
41 out.println("Please use the POST method!");
42 }
43 }
44
45 /**
46 * Handles the HTTP <code>POST</code> method.
47 *
48 * @param request the servlet request.
49 * @param response the servlet response.
50 * @throws ServletException if a servlet-specific error occurs.
51 * @throws IOException if an I/O error occurs.
52 */
53 @Override
54 protected void doPost(HttpServletRequest request, HttpServletResponse response)
55 throws ServletException, IOException {
56 response.setContentType("text/html;charset=UTF-8");
57
58 try (PrintWriter out = response.getWriter()) {
59 String firstName = request.getParameter("first_name");
60 String lastName = request.getParameter("last_name");
61 String email = request.getParameter("email");
62
63 if (firstName.isEmpty()) {
64 out.println("The first name is empty.");
65 return;
66 }
67
68 if (lastName.isEmpty()) {
69 out.println("The last name is empty.");
70 return;
71 }
72
73 if (email.isEmpty()) {
74 out.println("The email is empty.");
75 return;
76 }
77
78 FunnyPerson person = new FunnyPerson();
79 person.setFirstName(firstName);
80 person.setLastName(lastName);
81 person.setEmail(email);
82
83 try {
84 DataAccessObject.instance().addPerson(person);
85 out.println("Person " + person + " created!");
86 } catch (RuntimeException ex) {
87 out.println("Error: " + ex.getCause().getMessage());
88 }
89 }
90 }
91
92 /**
93 * Returns a short description of the servlet.
94 *
95 * @return a String containing servlet description
96 */
97 @Override
98 public String getServletInfo() {
99 return "This servlet adds new persons to the database.";
100 }
101}
102
103package net.coderodde.web.db.fun.controllers;
104
105import java.io.IOException;
106import java.io.PrintWriter;
107import javax.servlet.ServletException;
108import javax.servlet.annotation.WebServlet;
109import javax.servlet.http.HttpServlet;
110import javax.servlet.http.HttpServletRequest;
111import javax.servlet.http.HttpServletResponse;
112
113/**
114 * This controller creates the database if it is not yet created.
115 *
116 * @author Rodion "rodde" Efremov
117 * @version 1.6 (Aug 8, 2017)
118 */
119@WebServlet(name = "CreateDatabaseController", urlPatterns = {"/create"})
120public class CreateDatabaseController extends HttpServlet {
121
122
123 /**
124 * If not yet created, this request creates the database and the table.
125 *
126 * @param request the servlet request.
127 * @param response the servlet response.
128 * @throws ServletException if a servlet-specific error occurs.
129 * @throws IOException if an I/O error occurs.
130 */
131 protected void processRequest(HttpServletRequest request, HttpServletResponse response)
132 throws ServletException, IOException {
133 response.setContentType("text/html;charset=UTF-8");
134
135 try (PrintWriter out = response.getWriter()) {
136 try {
137 DataAccessObject.instance().createDatabase();
138 out.println("Database created!");
139 } catch (RuntimeException ex) {
140 out.println("Error: " + ex.getCause().getMessage());
141 }
142 }
143 }
144
145 /**
146 * Handles the HTTP <code>GET</code> method.
147 *
148 * @param request the servlet request.
149 * @param response the servlet response.
150 * @throws ServletException if a servlet-specific error occurs.
151 * @throws IOException if an I/O error occurs.
152 */
153 @Override
154 protected void doGet(HttpServletRequest request, HttpServletResponse response)
155 throws ServletException, IOException {
156 processRequest(request, response);
157 }
158
159 /**
160 * Handles the HTTP <code>POST</code> method.
161 *
162 * @param request the servlet request.
163 * @param response the servlet response.
164 * @throws ServletException if a servlet-specific error occurs.
165 * @throws IOException if an I/O error occurs.
166 */
167 @Override
168 protected void doPost(HttpServletRequest request, HttpServletResponse response)
169 throws ServletException, IOException {
170 processRequest(request, response);
171 }
172
173 /**
174 * Returns a short description of the servlet.
175 *
176 * @return a String containing servlet description.
177 */
178 @Override
179 public String getServletInfo() {
180 return "Creates the database and the table.";
181 }
182}
183
184package net.coderodde.web.db.fun.controllers;
185
186import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
187import java.sql.Connection;
188import java.sql.PreparedStatement;
189import java.sql.ResultSet;
190import java.sql.SQLException;
191import java.sql.Statement;
192import java.util.Objects;
193import java.util.regex.Matcher;
194import java.util.regex.Pattern;
195import net.coderodde.web.db.fun.model.FunnyPerson;
196
197public final class DataAccessObject {
198
199 /**
200 * For validating the email addresses.
201 */
202 public static final Pattern VALID_EMAIL_ADDRESS_REGEX =
203 Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$",
204 Pattern.CASE_INSENSITIVE);
205
206 /**
207 * The SQL command for inserting a person.
208 */
209 private static final String INSERT_PERSON_SQL =
210 "INSERT INTO funny_persons (first_name, last_name, email) VALUES " +
211 "(?, ?, ?);";
212
213 /**
214 * Creates a new database if not already created.
215 */
216 private static final String CREATE_DATABASE_SQL =
217 "CREATE DATABASE IF NOT EXISTS funny_db;";
218
219 /**
220 * Switches to 'funny_db'.
221 */
222 private static final String USE_DATABASE_SQL = "USE funny_db";
223
224 /**
225 * Creates the table if not already created.
226 */
227 private static final String CREATE_TABLE_SQL =
228 "CREATE TABLE IF NOT EXISTS funny_persons (n" +
229 "id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,n" +
230 "first_name VARCHAR(40) NOT NULL,n" +
231 "last_name VARCHAR(40) NOT NULL,n" +
232 "email VARCHAR(50) NOT NULL,n" +
233 "created TIMESTAMP);";
234
235 /**
236 * The SQL for selecting a user given his/her ID.
237 */
238 private static final String GET_USER_BY_ID_SQL =
239 "SELECT * FROM funny_persons WHERE id = ?;";
240
241 private final MysqlDataSource mysqlDataSource;
242
243 private DataAccessObject(MysqlDataSource mysqlDataSource) {
244 this.mysqlDataSource = Objects.requireNonNull(
245 mysqlDataSource,
246 "The MysqlDataSource is null.");
247 }
248
249 private static final DataAccessObject INSTANCE;
250
251 static {
252 MysqlDataSource mysqlDataSource = new MysqlDataSource();
253 mysqlDataSource.setUser("root");
254 mysqlDataSource.setPassword("your_password");
255 mysqlDataSource.setURL("jdbc:mysql://localhost:3306/funny_db");
256 INSTANCE = new DataAccessObject(mysqlDataSource);
257 }
258
259 public static DataAccessObject instance() {
260 return INSTANCE;
261 }
262
263 /**
264 * Adds a person to the database.
265 *
266 * @param person the person to add.
267 */
268 public void addPerson(FunnyPerson person) {
269 checkPerson(person);
270
271 try (Connection connection = mysqlDataSource.getConnection()) {
272 try (PreparedStatement statement =
273 connection.prepareStatement(INSERT_PERSON_SQL)) {
274 statement.setString(1, person.getFirstName().trim());
275 statement.setString(2, person.getLastName().trim());
276 statement.setString(3, person.getEmail().trim());
277 statement.executeUpdate();
278 }
279 } catch (SQLException ex) {
280 throw new RuntimeException(ex);
281 }
282 }
283
284 /**
285 * Creates the empty database and the table.
286 */
287 public void createDatabase() {
288 try (Connection connection = mysqlDataSource.getConnection()) {
289 try (Statement statement = connection.createStatement()) {
290 statement.executeUpdate(CREATE_DATABASE_SQL);
291 statement.executeUpdate(USE_DATABASE_SQL);
292 statement.executeUpdate(CREATE_TABLE_SQL);
293 }
294 } catch (SQLException ex) {
295 throw new RuntimeException(ex);
296 }
297 }
298
299 /**
300 * Gets a user by his/her ID.
301 *
302 * @param id the ID of the user.
303 * @return a {@code FunnyPerson}Â object or {@code null}Â if there is not such
304 * user.
305 */
306 public FunnyPerson getUserById(int id) {
307 try (Connection connection = mysqlDataSource.getConnection()) {
308 try (PreparedStatement statement =
309 connection.prepareStatement(GET_USER_BY_ID_SQL)) {
310 statement.setInt(1, id);
311
312 try (ResultSet resultSet = statement.executeQuery()) {
313 if (!resultSet.next()) {
314 return null;
315 }
316
317 FunnyPerson person = new FunnyPerson();
318
319 person.setId(resultSet.getInt("id"));
320 person.setFirstName(resultSet.getString("first_name"));
321 person.setLastName(resultSet.getString("last_name"));
322 person.setEmail(resultSet.getString("email"));
323 person.setCreated(resultSet.getDate("created"));
324
325 return person;
326 }
327 }
328 } catch (SQLException ex) {
329 throw new RuntimeException(ex);
330 }
331 }
332
333 private void checkPerson(FunnyPerson person) {
334 Objects.requireNonNull(person, "The person is null.");
335 Objects.requireNonNull(person.getFirstName(),
336 "The first name is null.");
337
338 Objects.requireNonNull(person.getLastName(), "The last name is null.");
339 Objects.requireNonNull(person.getEmail(), "The email is null.");
340
341 if (person.getFirstName().trim().isEmpty()) {
342 throw new IllegalArgumentException("The first name is empty.");
343 }
344
345 if (person.getLastName().trim().isEmpty()) {
346 throw new IllegalArgumentException("The last name is empty.");
347 }
348
349 if (!validate(person.getEmail().trim())) {
350 throw new IllegalArgumentException("Invalid email address.");
351 }
352 }
353
354 /**
355 * Checks the email address.
356 *
357 * @param email the email address to validate.
358 * @return {@code true} if {@code email} is a valid email address.
359 */
360 private static boolean validate(String email ) {
361 Matcher matcher = VALID_EMAIL_ADDRESS_REGEX .matcher(email );
362 return matcher.find();
363 }
364}
365
366package net.coderodde.web.db.fun.controllers;
367
368import com.google.gson.Gson;
369import java.io.IOException;
370import java.io.PrintWriter;
371import javax.servlet.ServletException;
372import javax.servlet.annotation.WebServlet;
373import javax.servlet.http.HttpServlet;
374import javax.servlet.http.HttpServletRequest;
375import javax.servlet.http.HttpServletResponse;
376import net.coderodde.web.db.fun.model.FunnyPerson;
377
378/**
379 * This controller is responsible for viewing persons.
380 *
381 * @author Rodion "rodde" Efremov
382 * @version 1.6 (Aug 8, 2017)
383 */
384@WebServlet(name = "ShowPersonController", urlPatterns = {"/show/*"})
385public class ShowPersonController extends HttpServlet {
386
387
388 /**
389 * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
390 * methods.
391 *
392 * @param request the servlet request.
393 * @param response the servlet response.
394 * @throws ServletException if a servlet-specific error occurs.
395 * @throws IOException if an I/O error occurs.
396 */
397 protected void processRequest(HttpServletRequest request, HttpServletResponse response)
398 throws ServletException, IOException {
399 response.setContentType("text/html;charset=UTF-8");
400
401 try (PrintWriter out = response.getWriter()) {
402 String path = request.getPathInfo();
403
404 if (path.startsWith("/")) {
405 path = path.substring(1);
406 }
407
408 String[] tokens = path.split("/");
409
410 if (tokens.length == 0) {
411 out.println("Error: At least the user ID is required.");
412 return;
413 }
414
415 String idString = tokens[0];
416 int id = -1;
417
418 try {
419 id = Integer.parseInt(idString);
420 } catch (NumberFormatException ex) {
421 out.println("Error: " + idString + " is not an integer.");
422 return;
423 }
424
425 FunnyPerson person = DataAccessObject.instance().getUserById(id);
426
427 if (person == null) {
428 out.println("Error: no person with ID = " + id + ".");
429 return;
430 }
431
432 String matchFirstName = null;
433
434 if (tokens.length == 2) {
435 matchFirstName = tokens[1];
436 }
437
438 if (!person.getFirstName().equals(matchFirstName)) {
439 response.sendRedirect("/DBWebFun/show/" + id + "/" +
440 person.getFirstName());
441 return;
442 }
443
444 Gson gson = new Gson();
445 out.println(gson.toJson(person));
446 }
447 }
448
449 /**
450 * Handles the HTTP <code>GET</code> method.
451 *
452 * @param request servlet request
453 * @param response servlet response
454 * @throws ServletException if a servlet-specific error occurs
455 * @throws IOException if an I/O error occurs
456 */
457 @Override
458 protected void doGet(HttpServletRequest request, HttpServletResponse response)
459 throws ServletException, IOException {
460 processRequest(request, response);
461 }
462
463 /**
464 * Handles the HTTP <code>POST</code> method.
465 *
466 * @param request servlet request
467 * @param response servlet response
468 * @throws ServletException if a servlet-specific error occurs
469 * @throws IOException if an I/O error occurs
470 */
471 @Override
472 protected void doPost(HttpServletRequest request, HttpServletResponse response)
473 throws ServletException, IOException {
474 processRequest(request, response);
475 }
476
477 /**
478 * Returns a short description of the servlet.
479 *
480 * @return a String containing servlet description
481 */
482 @Override
483 public String getServletInfo() {
484 return "Shows the user info via ID/first_name";
485 }
486}