Статьи

EE Servlet 3: простая обработка форм

Обработка форм в веб-приложении для большинства веб-разработчиков напоминает хлеб с маслом. Это не будет много пользы, если мы не сможем захватить ввод данных пользователем и обработать его. Поэтому я включил простой FormServlet в мой пример сервлета3, который продемонстрировал несколько часто используемых входов форм, с которыми вы можете столкнуться. Вот как это выглядит:

01
02
03
04
05
06
07
08
09
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
package zemian.servlet3example.web;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import zemian.service.logging.Logger;
 
@WebServlet("/form")
public class FormServlet extends HtmlWriterServlet {
    private static final Logger LOGGER = new Logger(FormServlet.class);
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HtmlWriter html = createHtmlWriter(req, resp);  
        String message = getMessage(req);
        
        html.header()
            .h(1, "User Data Form")
            .p(message)
            .println("<form method='post' action='form'>")
            .println("<p/>Username: <input type='text' name='username'/>")
            .println("<p/>Password: <input type='password' name='password'/>")
            .println("<p/>Choose a country: <select name='country' size='1'>")
            .println("<option default='true'>US</option>")
            .println("<option>China</option>")
            .println("<option>Korea</option>")
            .println("</select>")
            .println("<p/>Skills set: <input type='checkbox' name='skills' value='Java'/> Java")
            .println("<input type='checkbox' name='skills' value='Java EE'/>Java EE")
            .println("<input type='checkbox' name='skills' value='MySQL Database'/> MySQL Database")
            .println("<p/>Notes: <textarea name='notes' cols='50' rows='3'></textarea>")
            .println("<p/><input type='submit' value='Submit'/>")
            .println("</form>")
            .println(html.link("Back to Home", "/index"))
            .footer();
    }
 
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        LOGGER.info("Processing form.");
        Form form = new Form();
        form.setUsername(req.getParameter("username"));
        form.setPassword(req.getParameter("password"));
        form.setNotes(req.getParameter("notes"));
        form.setCountry(req.getParameter("country"));
        String[] skills = req.getParameterValues("skills");
        skills = (skills == null) ? new String[0] : skills;
        form.setSkills(Arrays.asList(skills));
        req.setAttribute("message", "Processed: " + form);
        doGet(req, resp);
    }
   
    private String getMessage(HttpServletRequest req) {
        String message = (String)req.getAttribute("message");
        if (message ==  null) {
            message = "";
        }
        return message;
    }
}

Как обычно, большинство форм отображаются с запросом http GET, а затем обрабатываются с помощью действия POST. Присмотритесь поближе и обратите внимание на то, как сервлет обрабатывает входные данные с единичными или множественными значениями. Они существуют, потому что форма HTML может позволить пользователям выбирать несколько значений из одного входного тега / виджета.

Один из распространенных шаблонов, который делают разработчики при обработке форм, — это захват входных данных в «объект команды», «объект переноса» или (в моем примере) объект «форма»; так что данные могут быть переданы на другой уровень вашего приложения для дальнейшей обработки. Это хороший дизайн, потому что он отделяет зависимости веб-слоя от сервисных уровней бэкэнд-уровня.

Другая часто встречающаяся область обработки форм — это проверка данных. Если вы захватите ваши данные как объект формы, то у вас, скорее всего, будет два уровня проверок. Один уровень — это когда вы извлекаете его сразу из http-запроса (обычно из ввода String), тогда вы можете проверить, является ли это обязательное поле или необязательным, является ли значение String конвертируемым в ожидаемый и желательный тип (целое число или дату и т. Д.). ). Второй уровень проверки может быть ниже на уровне службы, где у вас уже есть объект формы, построенный с правильными типами, но их значения могут быть недопустимыми в соответствии с требованиями вашего приложения. Наиболее распространенные недействительные данные связаны с тем, что они не соответствуют ограничениям базы данных и, следовательно, не могут их сохранить. Я не привел приведенный выше пример проверки, но вы можете легко улучшить сервлет и дополнительно изучить его самостоятельно.

Я хотел бы упомянуть еще одну заметку. Существует множество веб-фреймворков Java, которые уделяют большое внимание обработке форм, и они должны помочь вам легче разрабатывать приложения с меньшим количеством дублирующегося кода. Обычно это делается с очень конкретной моделью и стилем программирования, которые во многих случаях защищают вас от полного просмотра объекта HttpServletRequest. Все это хорошо (при условии, что фреймворк хорошего качества), но имейте в виду, что в большинстве случаев возникает проблема, в основном на уровне фреймворка или, что более вероятно, в вашем собственном коде, который использует фреймворк. И тогда вы будете тратить большую часть своего времени на отладку, изучая специфический для фреймворка домен, а не уровень спецификаций сервлета.

Для моего примера я стараюсь сосредоточиться только на EE API, поэтому я буду держаться подальше от любых дополнительных платформ, кроме стандартного API. Если вы новичок, я настоятельно рекомендую вам изучить API сервлетов и посмотреть, как обрабатывается форма, это дает вам более четкое представление о том, как поступают данные в веб-приложении. Если вы загляните дальше в стек Java EE, то на самом деле у него уже есть инфраструктура, которая называется JSF как часть стандартов EE 6. Это дизайн, чтобы помочь построить веб-страницы как модель компонентов; и это позволяет вам захватывать данные формы и автоматически связываться с объектом bean-компонента намного более плавным и интегрированным способом. JSF достойна своей темы для будущих сообщений.

Ссылка: EE Servlet 3: Простая обработка форм от нашего партнера JCG Земьяна Дена в блоге A Programmer’s Journal .