DCL 4.0
Loading...
Searching...
No Matches
EShopServlet.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#if __DCL_WINDOWS
4#include <windows.h>
5#endif
6
7#include <dcl/Charset.h>
8#include <dcl/Files.h>
9#include <dcl/IniFile.h>
10
11//#include <dcl/net/HttpCollection.h>
12#include <dcl/Html.h>
13
14#include "EShopServlet.h"
15#include "EShopSession.h"
16#include "VisitorBook.h"
17
18#if __DCL_DEBUG
19#undef __THIS_FILE__
20static const char_t __THIS_FILE__[] = __T("dcl/eshop/EShopServlet.cpp");
21#endif
22
23__DCL_BEGIN_NAMESPACE
24
25HTTP_SERVLET_INSTANCE(EShopServlet, L"온라인 쇼핑몰")
26
28
29EShopServlet::EShopServlet()
30{
31 m_pSQLConnPool = NULL;
32 m_pHead = NULL;
33 m_pFoot = NULL;
34 m_pViewOrder = NULL;
35 m_pViewProduct = NULL;
36 m_pViewShoppingBasket = NULL;
37}
38
40{
41 HttpServlet::onInitialize(); // 항상 true
42
43#if __DCL_WINDOWS
44#define INI_FILENAME L"HSAEShop_w.ini"
45#else
46#define INI_FILENAME L"HSAEShop.ini"
47#endif
48
49 String strIniFile = getIniFileName(INI_FILENAME);
50 if (strIniFile.isEmpty())
51 {
52 __DCL_TRACE1(L"not found : %ls\n", strIniFile.data());
53 return;
54 }
55
56 String strSQLDriverName;
57 String strSQLConnectionString;
58
59 try
60 {
61 IniFile ini(strIniFile);
62
63#ifdef __DCL_DEBUG
64 String strEnableDebugOut = ini.getString(L"DEBUG", L"ENABLE_DEBUG_OUT");
65 if (strEnableDebugOut.compareNoCase(L"FALSE") == 0)
66 HttpServletEx::m_bEnableDebugOut = false;
67#endif
68
69 strSQLDriverName = ini.getString(L"DATABASE", L"DRIVER");
70 strSQLConnectionString = ini.getString(L"DATABASE", L"CONNECT");
71
72 __DCL_TRACE3(L"%ls, %ls, %ls\n",
73 strIniFile.data(),
74 strSQLDriverName.data(),
75 strSQLConnectionString.data()
76 );
77
78 __strTemplateDir = ini.getString(L"HTML_TEMPLATE", L"DIR");
79
80 m_pSQLConnPool = new SQLConnectionPool(
81 strSQLConnectionString,
82 strSQLDriverName
83 );
84
85 m_pHead = new TextTemplate(readTemplate(L"header.html"));
86 m_pFoot = new TextTemplate(readTemplate(L"footer.html"));
87 m_pViewProduct = new TextTemplate(readTemplate(L"view_product.html"));
88 m_pViewShoppingBasket = new TextTemplate(readTemplate(L"view_shopping_basket.html"));
89 m_pViewOrder = new TextTemplate(readTemplate(L"view_order.html"));
90 }
91 catch (Exception* e) {
92 __DCL_TRACE1(L"Init Failed %ls\n", e->toStringAll().data());
93 e->destroy();
94
95 onCleanup();
96 }
97}
98
100{
101 if (m_pSQLConnPool) {
102 delete m_pSQLConnPool;
103 m_pSQLConnPool = NULL;
104 }
105
106 if (m_pHead) {
107 delete m_pHead;
108 m_pHead = NULL;
109 }
110
111 if (m_pFoot) {
112 delete m_pFoot;
113 m_pFoot = NULL;
114 }
115
116 if (m_pViewOrder) {
117 delete m_pViewOrder;
118 m_pViewOrder = NULL;
119 }
120
121 if (m_pViewProduct) {
122 delete m_pViewProduct;
123 m_pViewProduct = NULL;
124 }
125
126 if (m_pViewShoppingBasket) {
127 delete m_pViewShoppingBasket;
128 m_pViewShoppingBasket = NULL;
129 }
130
132 __DCL_TRACE0(L"onCleanup()\n");
133}
134
135
137{
138 if (!(ctx.methodNo() == HTTP_METHOD_GET
139 || ctx.methodNo() == HTTP_METHOD_POST))
140 {
141 // GET나 POST 아니면
142 ctx.setStatusCode(HTTP_STATUS_METHOD_NOT_ALLOWED);
143 return;
144 }
145
146 __DCL_ASSERT(m_pSQLConnPool != NULL);
147 __DCL_ASSERT(m_pHead != NULL);
148 __DCL_ASSERT(m_pFoot != NULL);
149 __DCL_ASSERT(m_pViewProduct != NULL);
150
151 SQLConnection* pSQLConn = m_pSQLConnPool->getConnection();
152 if (!pSQLConn) {
153 printError(ctx, L"데이터베이스 서버에 연결할 수 없습니다.");
154 return;
155 }
156
157 try {
158 if (pSQLConn->canTransact()) {
159 pSQLConn->startTrans();
160 }
161
162 Writer& out = ctx.writer();
163 EShopSession session(ctx, pSQLConn);
164 switch(session.command())
165 {
166 case CM_LOGIN :
167 if (session.login(ctx.__formMap))
169 else
171 break;
172 case CM_LOGOUT :
173 session.logout();
174 session.setCommand(CM_ABOUT);
175 }
176
177 // 복사본을 만들어 템플릿의 메크로들을 완성한다.
178
179 printPageHeader(out, session);
180
181 switch(session.command()) {
182 case CM_VIEW_PRODUCT: {
183 onViewProduct(ctx, session);
184 break;
185 }
186 case CM_VIEW_LOGIN_FORM: {
187 printLoginForm(out);
188 break;
189 }
191 onViewShoppingBasket(ctx, session);
192 break;
193 }
194 case CM_ORDER :
195 case CM_VIEW_ORDER: {
196 onViewOrder(ctx, session);
197 break;
198 }
199 case CM_VIEW_QNA: {
200 VisitorBook vb(
203 L"vcm",
204 *this);
205 if (!vb.onVisitorBook(ctx, out, pSQLConn)) {
206 printFile(out, L"notfound.html");
207 }
208 break;
209 }
210 case CM_SALES_REPORT: {
211 if (session.isAdmin())
212 onViewSalesReport(ctx, session);
213 else
214 printLoginForm(out);
215 break;
216 }
218 session.onViewSessions(
219 ctx.__queryMap,
220 out,
223 L"vses",
224 *this
225 );
226 break;
227 }
228 case CM_ABOUT: {
229 printFile(out, L"about.html");
230 break;
231 }
232 default: {
233 printFile(out, L"notfound.html");
234 }
235 }
236
237 if (pSQLConn->inTransaction()) {
238 pSQLConn->commitTrans();
239 }
240 m_pSQLConnPool->release(pSQLConn);
241 pSQLConn = NULL;
242
243 TextTemplate tplFooter = *m_pFoot;
244 out << tplFooter;
245
246 ctx.setContentType(L"text/html");
247 ctx.setStatusCode(HTTP_STATUS_OK); // HTTP_OK
248 }
249 catch (Exception* _e) {
250 if (pSQLConn) {
251 if (pSQLConn->inTransaction()) {
252 pSQLConn->rollbackTrans();
253 }
254 m_pSQLConnPool->release(pSQLConn);
255 }
256 throw _e;
257 }
258}
259
260void EShopServlet::printError(HttpServletContextEx& ctx, const String str)
261{
262 Writer& out = ctx.writer();
263 out << L""
264 "<!DOCTYPE html>\n"
265 "<html lang=\"ko-KR\">\n"
266 "<head>\n"
267 "<meta charset=\"UTF-8\">\n"
268 "<title>에러!</title>\n"
269 "</head>\n"
270 "<body>\n"
271 "<h3>에러가 발생하여 요청을 완료할 수 없습니다.</h3>\n"
272 "<hr>\n<p>"
273 << Html::format(str, 4, L"<p>", L"</p>\n")
274 << L"</p>\n"
275 << L"</body>\n</html>\n";
276
277 ctx.setContentType(L"text/html", L"utf-8");
278 ctx.setStatusCode(HTTP_STATUS_OK); // HTTP_OK
279}
280
281void EShopServlet::printLoginForm(
282 Writer& out
283 )
284{
285 TextTemplate tpl(readTemplate(L"login_form.html"));
286 String strHREF = String::format(L"?%ls=%d", COMMAND_STR, CM_LOGIN);
287 tpl.assign(L"HREF_LOGIN_ACTION", strHREF);
288
289 out << tpl;
290}
291
293{
296 const wchar_t* psz;
297};
298
299static MAIN_MENU menus[] =
300{
301 { false, CM_VIEW_PRODUCT, L"상품정보" },
302 { false, CM_VIEW_SHOPPING_BASKET, L"장바구니" },
303 { false, CM_VIEW_ORDER, L"주문정보" },
304 { false, CM_VIEW_QNA, L"Q&A" },
305 { true, CM_PRODUCT_MANAGEMENT, L"상품관리" },
306 { true, CM_SALES_REPORT, L"매출현황" },
307 { true, CM_SESSION_MANAGEMENT, L"세션관리" },
308 { false, CM_ABOUT, L"About" },
309// { false, CM_VIEW_LOGIN_FORM, L"로그인" }
310};
311
312void EShopServlet::printPageHeader(
313 Writer& out,
314 const EShopSession& session
315 )
316{
317 TextTemplate tplHeader = *m_pHead;
318
319 if (!session.isGuest())
320 {
321 StringBuilder str = L"<strong>" + session.userName();
322 if (session.isAdmin())
323 {
324 str += L"<span style=\"color:red\">";
325 str += L"(관리자 권한)</span>";
326 }
327 str += L"</strong> 님 로그인 하셨습니다";
328 tplHeader.assign(L"USER_HELLO", str);
329 }
330 else
331 tplHeader.assign(L"USER_HELLO", L"&nbsp");
332
333 // main menu
334 String strTitle;
335 for(unsigned int i = 0; i < (sizeof(menus) / sizeof(MAIN_MENU)); i++)
336 {
337 if (menus[i].bAdminOnly)
338 {
339 if (!session.isAdmin())
340 continue;
341 }
342
343 if (i)
344 tplHeader.append(L"HREF", L"<span style=\"color: red\"> | </span>");
345
346 if (menus[i].nCmd == session.command())
347 {
348 StringBuilder strHREF = L"<span style=\"color:blue\">";
349 strHREF += menus[i].psz;
350 strHREF += L"</span>\n";
351
352 tplHeader.append(L"HREF", strHREF);
353 strTitle = menus[i].psz;
354 }
355 else
356 {
357 String strHREF = String::format(L"<a class=\"menu\" href=\"?%ls=%d\">%ls</a>\n",
358 COMMAND_STR, menus[i].nCmd, menus[i].psz);
359 tplHeader.append(L"HREF", strHREF);
360 }
361 }
362
363 tplHeader.append(L"HREF", L"<span style=\"color: red\"> | </span>");
364
365 if (session.isGuest())
366 {
367 if (session.command() == CM_VIEW_LOGIN_FORM)
368 {
369 StringBuilder strHREF = L"<span style=\"color:blue\">";
370 strHREF += L"로그인";
371 strHREF += L"</span>\n";
372 tplHeader.append(L"HREF", strHREF);
373 strTitle = L"로그인";
374 }
375 else
376 {
377 String strHREF = String::format(L"<a class=\"menu\" href=\"?%ls=%d\">%ls</a>\n",
378 COMMAND_STR, CM_VIEW_LOGIN_FORM, L"로그인");
379 tplHeader.append(L"HREF", strHREF);
380 }
381 }
382 else
383 {
384 String strHREF = String::format(L"<a class=\"menu\" href=\"?%ls=%d\">%ls</a>",
385 COMMAND_STR, CM_LOGOUT, L"로그아웃");
386 tplHeader.append(L"HREF", strHREF);
387 }
388
389 if (strTitle.isEmpty())
390 tplHeader.erase(L"TITLE");
391 else
392 tplHeader.assign(L"TITLE", strTitle);
393 out << tplHeader;
394}
395
396void EShopServlet::printFile(
397 Writer& out,
398 const wchar_t* _filename
399 )
400{
401 out << readTemplate(_filename);
402}
403
404String EShopServlet::readTemplate(const wchar_t* _filename) const
406{
407 String path = __strTemplateDir;
408 if (!path.endsWith(L"/")) {
409 path = path + L"/";
410 }
411 path = path + _filename;
412
413 __DCL_TRACE1(L"readTemplate [%ls]\n", path.data());
414
415 UTF8Decoder dec;
416 return Files::readText(path, dec);
417}
418
419__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
wchar_t char_t
Definition Config.h:275
#define __DCL_THROWS1(e)
Definition Config.h:167
#define INI_FILENAME
#define COMMAND_STR
COMMAND_ID
@ CM_VIEW_SHOPPING_BASKET
@ CM_VIEW_PRODUCT
@ CM_ABOUT
@ CM_SESSION_MANAGEMENT
@ CM_LOGIN
@ CM_ORDER
@ CM_VIEW_ORDER
@ CM_PRODUCT_MANAGEMENT
@ CM_VIEW_QNA
@ CM_LOGOUT
@ CM_VIEW_LOGIN_FORM
@ CM_SALES_REPORT
@ HTTP_METHOD_POST
@ HTTP_METHOD_GET
@ HTTP_STATUS_METHOD_NOT_ALLOWED
@ HTTP_STATUS_OK
#define HTTP_SERVLET_INSTANCE(ServletClass, Description)
#define __DCL_TRACE0(psz)
Definition Object.h:375
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:376
#define __DCL_TRACE3(fmt, arg1, arg2, arg3)
Definition Object.h:378
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:228
#define __T(str)
Definition Object.h:44
virtual void onInitialize() __DCL_THROWS1(Exception *)
virtual void onCleanup() __DCL_THROWS1(Exception *)
String readTemplate(const wchar_t *filename) const __DCL_THROWS1(IOException *)
virtual void onService(HttpServletContextEx &ctx) __DCL_THROWS1(Exception *)
const String & userName() const
bool login(ListedStringToStringArrayMap &params)
void onViewSessions(ListedStringToStringArrayMap &params, Writer &out, const String &strMainCommand, int nMainCommandID, const String &strCommandID, const EShopServlet &_servlet)
void setCommand(int nCM)
bool isGuest() const
bool isAdmin() const
int command() const
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
static String readText(const String &_filename) __DCL_THROWS1(IOException *)
Definition Files.cpp:437
static String format(const String &_str, int _tab2Space, const String &_beginOfLine, const String &_endOfLine)
Definition Html.cpp:123
StringWriter & writer()
virtual void onInitialize() __DCL_THROWS1(Exception *)
virtual void onCleanup() __DCL_THROWS1(Exception *)
String CharsetConvertException *bool canTransact() const
void rollbackTrans() __DCL_THROWS1(SQLException *)
bool inTransaction() const
void commitTrans() __DCL_THROWS1(SQLException *)
void CharsetConvertException *void startTrans() __DCL_THROWS1(SQLException *)
bool onVisitorBook(HttpServletContextEx &ctx, Writer &out, SQLConnection *pSQLConn)
const wchar_t * psz
COMMAND_ID nCmd