소개
사용 된 기술
요구 사항 분석
데이터 모델
응용 프로그램 아키텍처
데이터 계층
컨트롤러
액션 처리기
보기
필터
결과
할머니 활동을위한 Java 기반 웹 응용 프로그램. 이 웹 애플리케이션을 통해 최신 웹 브라우저를 통해 Todos를 만들고 읽고 업데이트 할 수 있습니다. 응용 프로그램은 또한 AAA를 구현합니다. 즉, 모든 사용자가 자체 계정을 가지고 있고 자신의 TODO 목록 등이 비공개임을 의미합니다.
이 문서는 초보자를위한 것이 아닙니다. 이 문서와 관련 응용 프로그램을 이해하려면 아래 기술에 대해 잘 알고 있어야합니다.
자바
서블릿, JSP
아파치 톰 캣
MySQL
HTML
Apache Netbeans IDE
파이어 폭스
이것은 전적으로 백엔드 프로젝트입니다. 따라서 CSS, JavaScript와 같은 프론트 엔드 기술은 사용되지 않습니다. 이 프로젝트의 목표는 Java Servlet API의 다른 조각이 어떻게 작동하는지 효과적으로 배우고 보여주는 것입니다.
요구 사항 분석으로 시작하여 웹 응용 프로그램을 개발할 것입니다. 그런 다음 데이터베이스 디자인으로 넘어갑니다. 데이터는 모든 웹 응용 프로그램의 중심입니다. 거의 모든 사용 사례는 데이터를 처리합니다. 웹 애플리케이션의 데이터 모델이 준비되면 응용 프로그램의 아키텍처를 설계합니다. 이 단계에서는 응용 프로그램이 다른 HTTP 작업에 어떻게 동작하는지 살펴 보겠습니다. 응용 프로그램 사용자가 수행 한 모든 작업은 HTTP를 통해 이루어지기 때문입니다. 우리는 가능한 모든 사용자 조치를 생각하고 명확하게 정의 할 것입니다. 다음으로, 우리는 인터페이스와 클래스를 설계하는 것으로 넘어갑니다.
우리의 응용 프로그램을 위해, 우리는 Todo가 우리에게 무엇인지 정의하는 것으로 시작합니다. TODO는 달성 해야하는 작업입니다. 우리는 그러한 과제 목록을 만들어 사기꾼의 삶을 살 수 있도록 도와줍니다. 우리는 작업을 수행 한 작업을 수행 할 때 목록을 계속 추적합니다. 우리를위한 TODO 항목에는 아래 속성이 있습니다.
처음에 작업은 상태 'Todo'상태를 갖습니다. 작업을 시작하면 '진행중인'으로 변경합니다. 작업이 완료되면 상태를 '완료'로 표시합니다.
우리는 응용 프로그램이 여러 사용자를 지원하기를 원합니다. 그리고 모든 사용자는 자신의 개인 목록이 있어야합니다. 따라서 사용자는 다른 사람의 할 일 목록을 볼 수 없습니다. 사용자는 사용자 이름으로 식별되어야하며, 이는 당사의 유효한 이메일 주소입니다. 사용자에게는 응용 프로그램에 대한 계정이 제공됩니다. 따라서 계정에는 아래 속성이 있습니다.
우리는 계정 만 관리하기 위해 '관리자'계정을 원합니다. 관리자 계정은 사용자 이름 'admin'을 사용해야합니다. 관리자 사용자는 다음과 같습니다.
마지막 두 항목은 관찰 할 가치가 있습니다. 일반적으로 '관리자'권리가있는 사용자는 모든 사람의 정보에 액세스 할 수 있다고 생각됩니다. 우리는 그런 것을 원하지 않습니다. 또한 우리는 이미 '관리자'계정이 계정을 관리하기위한 것이라고 이미 정의했습니다. TODO 목록을 관리하는 것이 아닙니다. '관리자'사용자 계정은 자주 사용되지 않습니다. 특별한 목적만을 의미합니다. 응용 프로그램의 경우 하나의 사용자 계정이 '관리자'계정을 처리 할 것으로 예상됩니다. 따라서 필요한 경우에만 '관리자'자격 증명을 사용하여 로그인하는 사람과 동일합니다. 모든 계정을 관리하기 위해 'admin'계정을 사용하는 기존 사용자 계정이므로 관리자 계정에 대해 별도의 작업 목록을 원하지 않습니다. 그것은 어떤 목적도 제공하지 않습니다.
우리는 할 일 목록이 항상 지속되기를 원합니다. 즉, TODO 항목이 사용자가 성공적으로 생성되면 절대 삭제할 수 없습니다. 마찬가지로 사용자 계정도 삭제하고 싶지 않습니다. 결론적으로, 우리는 응용 프로그램에서 '삭제'작업을 지원하고 싶지 않습니다. 따라서 우리는 CRUD에서만 CRU를 지원합니다.
우리는 응용 프로그램이 개인 TODO 목록을 유지하기를 원하기 때문에 응용 프로그램이 로그인 및 로그 아웃 메커니즘을 제공하기를 원합니다. 이것을 '인증'이라고합니다. 'admin'을 포함한 모든 사용자는 먼저 스스로 인증해야합니다. 성공적인 인증이 발생하면 사용자가 작업 공간으로 리디렉션됩니다. 우리는 두 가지 유형의 사용자 (하나의 관리자 및 다른 일반)에 대해 논의하기 때문에 응용 프로그램에 두 가지 유형의 작업 공간이 있습니다. 관리자 사용자는 사용자 계정 관리 작업 공간 만 작업해야합니다. 일반 사용자는 TODO List Management Worksce 와만 협력해야합니다. 둘 다 독점적입니다. 일반 사용자는 관리자의 작업 공간을 볼 수 없습니다. 관리자 사용자는 일반 사용자의 작업 공간을 볼 수 없습니다. 이것을 '승인'이라고합니다.
위의 요구 사항 외에도 응용 프로그램이 사용자의 로그인 및 로그 아웃 타임 스탬프의 세부 정보를 저장하려고합니다. 이를 통해 우리는 응용 프로그램에서 사용자의 활동을 추적하고 있습니다. 이것은 정확히 AAA의 '회계'가 아니지만 응용 프로그램의 경우이를 '회계'로 부르는 목적으로 사용됩니다.
지금까지 수집 한 요구 사항에 따라 응용 프로그램의 아래 엔터티에 대한 데이터를 저장해야한다는 것을 이해합니다.
몇 가지 계정에 대한 예제 :
| 계정 ID | 사용자 이름 | 이름 | 성 | 비밀번호 | 만들어졌습니다 | 상태 |
|---|---|---|---|---|---|---|
| 1 | 관리자 | 관리자 | 사용자 | 비밀번호 | 2020-05-06 17:34:04 | 활성화 |
| 2 | [email protected] | 남자 | 존스슨 | Oneword | 2020-05-07 12:34:04 | 장애가 있는 |
| 3 | [email protected] | 에릭 | 에릭슨 | 트위 와드 | 2020-05-08 13:34:04 | 활성화 |
| 4 | [email protected] | 어록 | 메리 | THREEWORD | 2020-05-09 11:34:04 | 활성화 |
우리는 계정 상태가 테이블 전체에 반복되는 것을 본다. 따라서 데이터베이스 정규화의 일부로 반복 데이터를 별도의 테이블에 넣는 것이 좋습니다. 뒤에는 몇 가지 좋은 이유가 있습니다. 말하자면, 우리는 100 명의 사용자가 있습니다. 또한 활성화 및 비활성화 된 단어를 각각 1과 2로 바꾸려고합니다. 테이블의 모든 행의 상태 열을 수정해야합니다. 수천 행이있는 테이블을 수정하는 것이 얼마나 번거로운 지 상상해보십시오! 고맙게도 구조에서 데이터베이스 정규화!
정규화 후, 우리는 두 개의 테이블 - account_statuses 및 계정이 있습니다.
Account_statuses
| ID | 상태 |
|---|---|
| 1 | 활성화 |
| 2 | 장애가 있는 |
계정
| 계정 ID | 사용자 이름 | 이름 | 성 | 비밀번호 | 상태 ID |
|---|---|---|---|---|---|
| 1 | 관리자 | 관리자 | 사용자 | 비밀번호 | 1 |
| 2 | [email protected] | 남자 | 존스슨 | Oneword | 2 |
| 3 | [email protected] | 에릭 | 에릭슨 | 트위 와드 | 1 |
| 4 | [email protected] | 어록 | 메리 | THREEWORD | 2 |
마찬가지로 작업을위한 세 가지 테이블이 있습니다.
task_statuses
| ID | 상태 |
|---|---|
| 1 | TODO |
| 2 | 진행 중 |
| 3 | 완료 |
task_priorities
| ID | 우선 사항 |
|---|---|
| 1 | 중요하고 긴급합니다 |
| 2 | 중요하지만 긴급하지는 않습니다 |
| 3 | 중요하지는 않지만 긴급합니다 |
| 4 | 중요하지 않고 긴급하지 않습니다 |
작업
| 작업 ID | 계정 ID | 세부 | 만들어졌습니다 | 사선 | 마지막으로 업데이트되었습니다 | 상태 ID | 우선 순위 ID |
|---|---|---|---|---|---|---|---|
| 1 | 2 | 연필을 구입하십시오. | 2019-05-06 17:40:03 | 2019-05-07 17:40:03 | 2 | 1 | |
| 2 | 3 | 책을 사십시오. | 2019-05-07 7:40:03 | 2019-05-07 17:40:03 | 2019-05-07 23:40:03 | 2 | 1 |
마지막으로 계정 세션 데이터를 저장해야 할 또 다른 요구 사항도 있습니다. 아래 표에 표시된대로 저장해야합니다.
계정 _sessions
| 세션 ID | 계정 ID | 세션이 생성되었습니다 | 세션 종료 |
|---|---|---|---|
| ASD1GH | 1 | 2019-05-06 17:40:03 | 2019-05-06 18:00:03 |
일반적으로 엔터프라이즈 애플리케이션에서 ID는 정수로 저장되지 않습니다. 정수를 사용하여 누군가가 다른 정보를 쿼리하는 것이 더 쉽기 때문입니다! 실제 응용 분야에서 ID는 숫자가 아니라 영숫자이며 최대 100 자입니다. 따라서 누군가가 다른 신분증을 추측하는 것을 불가능하게 만듭니다!
우리는 데이터베이스를 MySQL에서 'todo'로 호출합니다. 위의 정보를 기반으로 구축 된 데이터 모델은 다음과 같습니다.

우리는 유명하고 널리 사용되는 MVC 2 Desgin 패턴에 따라이 응용 프로그램을 개발할 것입니다. 아래 그림은 앱 용 MVC를 구현하는 방법을 보여줍니다. 
우리의 응용 프로그램은 조치 기반입니다. 사용자가 응용 프로그램에 HTTP 요청을 보내면 응용 프로그램의 해당 조치로 변환합니다. 우리가 지원하는 조치는 생성, 읽기 및 업데이트 (CRU)입니다. 우리의 응용 프로그램은 본질적으로 데이터 중심입니다. 데이터베이스의 조치를 용이하게합니다. 사용자가 인증 및 인증 메커니즘을 통해 원격 데이터베이스에 데이터를 안전하고 안전하게 저장하고 관리 할 수 있도록 도와줍니다. 데이터베이스에 대한 HTML 및 HTTP 기반 인터페이스 역할을합니다.
사용자가 응용 프로그램에 HTTP 요청을 할 때 요청 된 데이터를 HTML 형식으로 보냅니다. HTML은 사용자가 웹 애플리케이션과 상호 작용할 수 있도록 링크 및 양식을 지원합니다. 링크는 정보를 검색/get (http get) 정보를 검색하는 데 사용되며 양식은 데이터 (HTTP Post)를 웹 응용 프로그램에 게시하는 데 사용됩니다.
따라서 HTTP 요청을 조치로 변환하는 방법은 다음과 같습니다.
| HTML 요소 | HTTP 방법 | 응용 프로그램 조치 |
|---|---|---|
| 하이퍼 링크 | http를 얻습니다 | 자세한 내용을 읽으십시오 |
| 형태 | HTTP 게시물 | 생성 또는 업데이트 |
http get query 매개 변수로 데이터를 URL로 보냅니다. HTTP Post는 데이터를 HTTP 요청 본문으로 보냅니다. HTTP Post는 URL을 통해 데이터를 공개하지 않지만 HTTP는 얻을 수 있습니다. 따라서 HTTP Get은 로그인 자격 증명을 전송하는 데 적합하지 않습니다. 아무도 HTTP 요청 URL에 사용자 이름과 암호가 추가 된 것을보고 싶어하지 않습니다! HTTP 게시물을 사용하여 로그인하는 동안 사용자의 자격 증명을 보냅니다.
그래서 우리는 HTTP, HTML 및 데이터베이스를 어떻게 사용할 것인지 결정했습니다. HTTP 기반 애플리케이션의 아키텍처를 결정하는 데 필수적인 HTTP의 또 다른 개념이 있습니다. URL- 균일 자원 로케이터입니다. 다음은 exames.com 서버에서 호스팅 된 'webapp'이라는 웹 응용 프로그램의 예제입니다.
http://www.example.com/webapp/details?id=12
위의 예에서 URL은 'HTTP'가 프로토콜, www.example.com 은 도메인 이름 또는 서버 이름, 'WebApp'은 서버에 배포 된 응용 프로그램 컨텍스트이며 '세부 사항'은 HTTP 요청을 보내는 응용 프로그램입니다. 'ID'는 '12'값으로 '세부 사항'으로 전달하는 쿼리 매개 변수입니다. 쿼리 매개 변수는 웹 애플리케이션으로 웹 애플리케이션에 매개 변수를 전달하고 웹 애플리케이션에서 응답하여 관련 컨텐츠를 다시받는 메커니즘을 제공합니다. 예를 들어, 웹 서버에서 실행되는 날씨 응용 프로그램을 상상해보십시오. 모든 위치의 날씨 보고서 목록을 제공하는 대신 웹 애플리케이션에 쿼리 매개 변수로 위치를 선택할 수 있습니다. 그런 다음 응용 프로그램은 선택 위치의 날씨 세부 사항에 응답하여 보냅니다.
웹 응용 프로그램은 PC에서 실행되는 응용 프로그램과 달리 웹 서버에서 실행됩니다. 웹 서버에서 실행되는 Java 응용 프로그램을 서블릿이라고합니다. 서블릿은 웹 응용 프로그램을 모방합니다. 그들은 컨테이너 내부로 뻗어 있습니다. Apache Tomcat은 이러한 컨테이너의 인기있는 예입니다. 컨테이너 소프트웨어는 원시 HTTP 요청 및 응답을 Java 객체로 변환하고 서블릿을 제공합니다. 정적 웹 사이트는 모든 HTTP 요청에 대해 동일한 컨텐츠를 제공합니다. 그러나 서블릿은 모든 HTTP 요청에 대해 뚜렷한 동적 컨텐츠를 생성 할 수 있습니다.
우리가 구축하는 Todo 웹 앱에는 서블릿, 필터, JSP 파일, 데이터베이스 클래스, pojos 등 여러 부품이 포함됩니다. 컨테이너 (TOMCAT)의 하나의 응용 프로그램 컨텍스트 (또는 응용 프로그램 환경)에 따라 모두 함께 두십시오. 우리는이 응용 프로그램 컨텍스트를 'Todo'라고 부릅니다. 따라서 포트 8080의 PC에서 Tomcat을 실행하는 경우 응용 프로그램 컨텍스트 'Todo'에 URL을 통해 액세스 할 수 있습니다.
http://localhost:8080/todo/
당사의 데이터 계층은 JDBC DataSource 위에 DAO 패턴 및 공장 패턴의 구현으로 구성됩니다. 우리는 연결 풀링의 이점을 거두기를 원하기 때문에 DriverManager 대신 JDBC DataSource를 선택합니다.
우리는 단지 '메인'이라는 컨트롤러 역할을하는 1 개의 서블릿이 있습니다. 사용자의 HTTP 요청은 우리에게 조치입니다. 따라서 컨트롤러 서블릿의 목적은 HTTP 요청에 대한 적절한 조치 만 선택하는 것입니다. 컨트롤러 서블릿은 액션 핸들러를 선택하고 사용자의 요청에 따라이를 건네줍니다. 컨트롤러에 작업 실행 단계를 작성하지 않습니다. 우리는 그것을 깨끗하고 마른 상태로 유지합니다. 그 목적은 액션 핸들러를 '선택'하는 것입니다. 행동 자체를 '실행'하지 마십시오. 작업 핸들러가 요청 된 작업을 실행 한 후 컨트롤러는 작업 핸들러의 응답으로 수행 할 '다음 단계'를 수신합니다. 컨트롤러의 작업은 요청 된 응답을 수행하는 리소스를 간단히 선택하는 것입니다. 결론적으로, 우리는 컨트롤러를 모든 비즈니스 논리에서 멀리 떨어 뜨립니다.
컨트롤러 서블릿을 URI 패턴 /app/* 에 매핑해야합니다. 따라서 컨트롤러 서블릿은 패턴 /app/ 따르는 모든 URI를 처리합니다.
사용자가 요청한 조치는 응용 프로그램의 비즈니스 로직입니다. 액션 핸들러는 MVC 구현의 모델 입니다. 모든 작업은 작업 인터페이스를 구현해야합니다.
public interface Action {
/*
An action is supposed to execute and return results. ActionResponse represents the response.
*/
public abstract ActionResponse execute ( HttpServletRequest request , HttpServletResponse response )
throws Exception ;
}행동은 실행 및 결과를 반환해야합니다. 우리는 그러한 결과에 대한 특별 수업을 만듭니다 - ActionResponse. 액션 핸들러는 '전진'또는 '리디렉션'을 선택할 수 있습니다.
public class ActionResponse {
private String method ;
private String viewPath ;
public ActionResponse () {
this . method = "" ;
this . viewPath = "" ;
}
public void setMethod ( String method ) {
this . method = method ;
}
public String getMethod () {
return this . method ;
}
public void setViewPath ( String viewPath ) {
this . viewPath = viewPath ;
}
public String getViewPath () {
return this . viewPath ;
}
@ Override
public String toString () {
return this . getClass (). getName ()+ "[" + this . method + ":" + this . viewPath + "]" ;
}
}우리는 공장 디자인 패턴을 구현합니다. 우리는 공장 클래스 -ActionFactory- 우리에게 필요한 액션 핸들러 클래스를 제공합니다.
public class ActionFactory {
private static Map < String , Action > actions = new HashMap < String , Action >() {
{
put ( new String ( "POST/login" ), new LoginAction ());
put ( new String ( "GET/login" ), new LoginAction ());
put ( new String ( "GET/logout" ), new LogoutAction ());
put ( new String ( "GET/admin/accounts/dashboard" ), new AdminAccountsDashboardAction ());
put ( new String ( "GET/admin/accounts/new" ), new AdminNewAccountFormAction ());
put ( new String ( "POST/admin/accounts/create" ), new AdminCreateAccountAction ());
put ( new String ( "GET/admin/accounts/details" ), new AdminReadAccountDetailsAction ());
put ( new String ( "POST/admin/accounts/update" ), new AdminUpdateAccountAction ());
put ( new String ( "GET/tasks/dashboard" ), new UserTasksDashboardAction ());
put ( new String ( "GET/tasks/new" ), new UserNewTaskFormAction ());
put ( new String ( "GET/tasks/details" ), new UserReadTaskDetailsAction ());
put ( new String ( "POST/tasks/create" ), new UserCreateTaskAction ());
put ( new String ( "POST/tasks/update" ), new UserUpdateTaskAction ());
put ( new String ( "GET/users/profile" ), new UserReadProfileAction ());
put ( new String ( "POST/users/update" ), new UserUpdateProfileAction ());
}
;
};
public static Action getAction ( HttpServletRequest request ) {
Action action = actions . get ( request . getMethod () + request . getPathInfo ());
if ( action == null ) {
return new UnknownAction ();
} else {
return action ;
}
}
}컨트롤러 서블릿의 목적은 다음과 같습니다.
protected void processRequest ( HttpServletRequest request , HttpServletResponse response )
throws ServletException , IOException {
Action action = ActionFactory . getAction ( request );
try {
ActionResponse actionResponse = action . execute ( request , response );
if ( actionResponse . getMethod (). equalsIgnoreCase ( "forward" )) {
System . out . println ( this . getClass (). getCanonicalName () + ":forward:" + actionResponse );
this . getServletContext (). getRequestDispatcher ( actionResponse . getViewPath ()). forward ( request , response );
} else if ( actionResponse . getMethod (). equalsIgnoreCase ( "redirect" )) {
System . out . println ( this . getClass (). getCanonicalName () + ":redirect:" + actionResponse );
if ( actionResponse . getViewPath (). equals ( request . getContextPath ())) {
response . setHeader ( "Cache-Control" , "no-cache, no-store, must-revalidate" );
response . setHeader ( "Pragma" , "no-cache" );
response . setDateHeader ( "Expires" , 0 );
}
response . sendRedirect ( actionResponse . getViewPath ());
} else if ( actionResponse . getMethod (). equalsIgnoreCase ( "error" )) {
System . out . println ( this . getClass (). getCanonicalName () + ":error:" + actionResponse );
response . sendError ( 401 );
} else {
System . out . println ( this . getClass (). getCanonicalName () + ":" + actionResponse );
response . sendRedirect ( request . getContextPath ());
}
} catch ( Exception e ) {
e . printStackTrace ();
}
} 아래 표는 응용 프로그램에 응답하는 HTTP 요청 및 관련 조치 처리기의 목록을 보여줍니다.
| 사용자의 의도 된 조치 | HTTP 요청 URI | 액션 핸들러 |
|---|---|---|
| 빈 로그인 자격 증명을 제출하십시오 | GET /app/login | 로그인 |
| 로그인 자격 증명을 제출하십시오 | POST /app/login | 로그인 |
| 계정 대시 보드를 얻습니다 | GET /app/admin/accounts/dashboard | adminAccountsDashBoardAction |
| 새 계정 양식을 얻으십시오 | GET /app/admin/accounts/new | adminnewaccountformaction |
| 새 계정 세부 정보를 제출하십시오 | POST /app/admin/accounts/create | admincreateAcCountaction |
| 계정의 세부 정보를 얻으십시오 | GET /app/admin/accounts/details?id=xx | adminReadAccountDetailSaction |
| 계정의 세부 사항을 업데이트하십시오 | POST /app/admin/accounts/update | AdminupdateAcCountaction |
| 작업 대시 보드를 가져옵니다 | GET /app/tasks/dashboard | USERTASKSDASHBORTACTION |
| 새로운 작업 양식을 얻으십시오 | GET /app/tasks/new | usernewtaskformaction |
| 새로운 작업 세부 정보를 제출하십시오 | POST /app/tasks/create | userCreatEtAskaction |
| 작업에 대한 세부 정보를 얻으십시오 | GET /app/tasks/details?id=xx | UserReadtaskDetailsAction |
| 작업의 세부 사항을 업데이트하십시오 | POST /app/tasks/update | userupdateTaskaction |
| 내 프로필의 세부 정보를 얻으십시오 | GET /app/users/profile | USERREADPROFILEACTION |
| 내 프로필 세부 정보를 업데이트하십시오 | POST /app/users/update | userupdateprofileaction |
| 로그 아웃 | GET /app/logout | 로그 아웃 |
작업 핸들러의 작업은 비즈니스 로직을 실행하고 사용자의 요청에 대한 응답으로 적절한 보기 구성 요소를 선택하는 것입니다. 아래 표는 모든 동작 핸들러 및 뷰 구성 요소를 보여줍니다.
| 액션 핸들러 | 구성 요소를 봅니다 |
|---|---|
| 로그인 | /WEB-INF/pages/admin/accounts/dashboard.jsp/WEB-INF/pages/tasks/dashboard.jsp |
| adminAccountsDashBoardAction | /WEB-INF/pages/admin/accounts/dashboard.jsp |
| adminnewaccountformaction | /WEB-INF/pages/admin/accounts/newAccount.jsp |
| admincreateAcCountaction | /WEB-INF/pages/admin/accounts/createAccountResult.jsp |
| adminReadAccountDetailSaction | /WEB-INF/pages/admin/accounts/accountDetails.jsp |
| AdminupdateAcCountaction | /WEB-INF/pages/admin/accounts/updateAccountResult.jsp |
| USERTASKSDASHBORTACTION | /WEB-INF/pages/tasks/dashboard.jsp |
| usernewtaskformaction | /WEB-INF/pages/tasks/newTask.jsp |
| userCreatEtAskaction | /WEB-INF/pages/tasks/createTaskResult.jsp |
| UserReadtaskDetailsAction | /WEB-INF/pages/tasks/taskDetails.jsp |
| userupdateTaskaction | /WEB-INF/pages/tasks/updateTaskResult.jsp |
| USERREADPROFILEACTION | /WEB-INF/pages/users/viewProfile.jsp |
| userupdateprofileaction | /WEB-INF/pages/users/updateProfileResult.jsp |
| 알 수없는 행동 | /WEB-INF/pages/users/unknownAction.jsp |
보기 구성 요소는 사용자에게 전송 될 필요한 HTML 응답을 빌드합니다. 구성 요소보기 작업 핸들러가 설정 한 메시지를 읽고 사용자에게 표시합니다.
우리는 필터를 사용하여 들어오는 HTTP 요청을 가로 채립니다. 요청이 컨트롤러 서블릿에 전달되기 전에 모든 필터가 사용됩니다. 들어오는 HTTP 요청은 인증 필터로 처음 처리됩니다. 이 필터를 통해 사용자가 이미 로그인되었는지 여부를 확인합니다. 로그인하지 않으면 사용자를 로그인 페이지로 리디렉션합니다. 인증 필터를 성공적으로 전달하면 HTTP 요청이 두 개의 필터로 가로 채게됩니다. 이 필터에서 URI 경로를 확인하고 사용자는 '관리자'또는 일반 사용자입니다. 일반 사용자가 'Admin'URI 경로에 액세스하려고하는 경우 그러한 액세스를 방지합니다. '관리자'사용자가 관련 URI 경로에 액세스하려고하는 경우 그러한 액세스를 방지합니다.
/app/admin/* 로 시작하여 'admin'만이 URI에 액세스 할 수 있으며 /app/tasks/* 로 시작하여 정상적인 사용자 만 URI에 액세스 할 수 있습니다. 기타 URIS /app/login , /app/logout , /app/users/* 는 둘 다 액세스 할 수 있습니다.
우리는 우리가 발송하는 응답을 가로 채지 않습니다.
따라서 응용 프로그램의 모습은 다음과 같습니다. 단순성을 위해 UI 평원을 보관했습니다. CSS 또는 JavaScript가 없습니다.










