ã¿ã¤ãã«ã®éãã§ãããããã°ãä½ãã¾ããã以ä¸ã®URLã§ã¡ãã£ã¨åãã試é¨éç¨ãã¦ãã¾ãã
K.Maebashi's blog
https://kmaebashi.com/blog/kmaebashiblog
表å´ã®ç»é¢ã¯ãã®ãªã³ã¯ããè¦ã¦ããã ãã¨ãã¦ã管çè (ããã°è¨äºãæ¸ã人)åãã®ç»é¢ã¯ãããªæãã§ã(ã¯ãªãã¯ã§æ¡å¤§ãã¾ã)ã
è¦ãã¨ãããããã«ãç»åã¯è²¼ãã¾ãããæç« ãæ¸ãã¨ããã¯ãã ã®ããã¹ãã¨ãªã¢ã«ãªã£ã¦ãã¦ãæåã«è²ãä»ããã太åã«ããããããªããããã¹ãã¨ãã£ã¿ã®æ©è½ã¯ããã¾ããããªããããã¹ãã¨ãã£ã¿ã¯å人ãä½æã§ä½ãã«ã¯ã¡ãã£ã¨è·ãéãã§ãããããªã¼ã§ä½¿ããã©ã¤ãã©ãªãããããããããã§ããç§ã¯ãã¾ãå¤é¨ã®ã©ã¤ãã©ãªã«é ¼ããããªãã®ã§ãããã«ãããã°ã¨ãã§ä½¿ããªããããã¹ãã¨ãã£ã¿ã£ã¦ãããããããã£ã¦ãããã¡ã«ä½ããªãã ãããããªããªã£ã¦çµå±HTMLç·¨éã¢ã¼ãã§HTMLããããã¨ãããã¨ãå¤ãããã«æãã¾ãâ»1ãã¾ãSNSãªã©ã§ãæåã®è£ 飾ã¯ã§ããªãããã§ãããã§å°ã£ã¦ããªã人ãå¤ããªããå¥ã«ä¸è¦ãªã®ã§ã¯ã¨æãã¾ãã
ä¸ã®ç»åãè¦ãã¨ããã»ã¯ã·ã§ã³1ãã¨åºã¦ãã¾ããã¤ã¾ãããã®ããã°ã§ã¯ãã²ã¨ã¤ã®ããã°è¨äºã¯ã²ã¨ã¤ã¾ãã¯è¤æ°ã®ãã»ã¯ã·ã§ã³ãããæ§æããã¾ããããã¦ã²ã¨ã¤ã®ã»ã¯ã·ã§ã³ã«ã¯ãããã¹ãã¨ãªã¢ã§è¨è¿°ããæç« é¨åãããããã¤ãã®ä¸ã«è¤æ°ã®åçãè²¼ãã¾ããåçã«ã¯ãã£ãã·ã§ã³ãä»ãããã¨ãã§ãã¾ãã
ã¾ããããããã®ãã¨ãã§ããã°ãã©ã£ãã«éã³ã«è¡ã£ããããæã®æ¥è¨ãããã¯æ¸ãããã§ããä»ã®ãã¨ãæ¸ããããªã£ãæã«æ¸ãããã©ããã¯ãä»å¾æ¸ããªããèãã¾ãã
ããã°ã©ã ã®ã½ã¼ã¹ãªã©ã¯è²¼ãã«ããã®ã§ãããã°ã©ãã³ã°ç³»ã®æè¡è¨äºã«ã¯åããªãã§ãããããã¯ãããã£ã¦Webãã¼ã¸ã®æ¹ã«æ¸ãã¦ãªã³ã¯ã ãè²¼ãã°ããããªãã¨æã£ã¦ãã¾ãã
ã½ã¼ã¹ã¯GitHubã«(åããã«ã¯ããããã足ãã¦ãªãã§ãã)
https://github.com/kmaebashi/blog
ãã®ããã°ã¯Javaã¨ãµã¼ãã¬ããã¨èªä½ãªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã§ä½ãã¾ãããDBã¯PostgreSQLã使ç¨ãã¦ãããDOMæä½ã®ããã«jsoupããã¹ã¯ã¼ãã®ããã·ã¥åã®ããã«jBCryptã«ä¾åãã¦ãã¾ãã
ãµã¼ããµã¤ãã§ã¬ã³ããªã³ã°ãã¾ãããã©ã¦ã¶ããGETãé£ãã§ããæã®æµãã¯ä¸å³ã®éãã
ãã©ã¦ã¶ããã®ãªã¯ã¨ã¹ããæåã«åããã®ã¯ãµã¼ãã¬ããã§ããããã®ãªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã§ã¯ããµã¼ãã¬ããã¯èªåã§æ¸ãã¾ããã½ã¼ã¹ã¯ãããªæãã
ç»åã¨ãJavaScriptã¨ãCSSã¨ãã®éçãªãã¡ã¤ã«ä»¥å¤ã®ãªã¯ã¨ã¹ãã¯ããã¹ã¦ãã®ãµã¼ãã¬ãããåãã¦ã次ã®ã«ã¼ã¿ã«æ¸¡ãã¾ããç»é¢ãAPIãã©ããªã«å¢ãã¦ããµã¼ãã¬ãããä¿®æ£ããå¿ è¦ã¯ãªãã®ã§ã1åããããµã¼ãã¬ãããæ¸ãã®ã¯èªåã§ãã£ã¦ãããã§ãããã
ç»åã¨ãJavaScriptã¨ãCSSã¨ã以å¤ã®ãªã¯ã¨ã¹ãããµã¼ãã¬ããã§åããããã«ã¯ãç»åã¨ãJavaScriptã¨ãCSSã¨ãã¨ãã以å¤ã®ãªã¯ã¨ã¹ãã®åºå¥ãã¤ããªããã°ããã¾ããããã®ããããweb.xmlã§ãæ¡å¼µå.pngã¨.jpgã¨.cssã¨.js以å¤ã¯ãã®ãµã¼ãã¬ããã«æ¸¡ããã¨ããè¨å®ãã§ããã°ããã®ã§ãããweb.xmlã®url-patternã¯ãã¯ã¤ã«ãã«ã¼ãã¯ä½¿ããããã«ããããé¤å¤ãããã¨ããæ¸ãæ¹ã¯ã§ãã¾ããããã®å¯¾å¿ã«ã¤ãã¦ã¯ä»¥åã¯ã¦ãªããã°ã®æ¹ã«æ¸ãã¾ããã
ãµã¼ãã¬ããã®web.xmlã§éçãã¡ã¤ã«ãé¤å¤ããæ¹æ³ ä»åããã®æ¹æ³ã使ã£ã¦ãã¾ããRouterã¯ããªã¯ã¨ã¹ããé©åãªControllerã«æ¯ãåããå¦ç(ã«ã¼ãã£ã³ã°)ãè¡ãã¾ãã
ãã®ãªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã§ã¯ãRouterã¯ããã¬ã¼ã ã¯ã¼ã¯ãæä¾ããRouterã¯ã©ã¹ãç¶æ¿ããã«ã¼ãã£ã³ã°ã®å¦çèªä½ã¯èªåã§æ¸ãã¾ãã
ãã®ç¨åº¦ã®ããã°ã§ãããããªãã®ç¨®é¡ã®URLãã«ã¼ãã£ã³ã°ããªããã°ãããªãããã§(ä»é²ã®URLä¸è¦§åç §)ããããè¨å®ãã¡ã¤ã«ã«æ¸ãããControllerã«ã¢ããã¼ã·ã§ã³ãä»ãã¦æ¯ãåãããã¨ãããããªãã¨ããã¦ãããã®ã§ãããããURLã®æ¥ä»é¨åã®è§£éã¨ããã°ã¤ã³ç¶æ ã®æç¡ã¨ããèããã¨ããããé¢åããã§ãããããããªãã³ã¼ãã§ã¬ãªã¬ãªæ¸ãã¦ãå¤ãããªãããªãã¨æã£ã¦ãã¾ãã
ãã®ããã°ã§ã¯ãSelectRoute.javaã§ã«ã¼ãã®æ±ºå®ãè¡ãããããå ã«BlogRouter.javaã§Controllerãå¼ã³åãã¦ãã¾ãã
Routerã§ã«ã¼ãã決ã¾ã£ããControllerãå¼ã³ãControllerã¯Serviceãå¼ã³ãServiceã¯DbAccessãå¼ã³ãã¨ããã®ããã®ãªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã«ãããå¼ã³åºãé層ã§ããããã®é層ãã¾ããã¨ãããControllerã®å¼ã³åºããServiceã®å¼ã³åºããDbAccessã®å¼ã³åºãã®ã¨ããã§ã¯ãããã¦ãã°ãããã¯åºåãã¦ããããã¨ããã§ãã
ãããããã¨ãããããã°ãJavaã®æ¨æºæ©è½ã®ç¯å²ãªããã¾ãControllerãServiceãDbAccessã®interfaceãæ¸ãã¦java.lang.reflect.Proxyã使ã£ã¦å®è£ ã¯ã©ã¹ã®ã¡ã½ãããå¼ã³åºããã¨ããæ¹æ³ãããã¾ãããã ããã®æ¹æ³ã¯ã¾ãinterfaceãæ¸ãã®ãé¢åã§ãããããã ããªãã¾ã ããIDEã§ã¡ã½ããã®å®è£ ã«ç´æ¥é£ã¹ããããã¸ãä¸ä¾¿ãªæãããã¤ã¦ãããã¨ããã£ã¦é¿ãã¾ãã(ã¨ããªãã¨ãè¨ã£ã¦ããã¡ã«IDEå´ãé²æ©ãã¦å®è£ ã«ç´æ¥é£ã¹ãããã«ãªã£ã¦ãããã¾ããã)ã
以åç§ã¯ããã ããã®è¨äºãåèã«Javassistã使ã£ã¦ã¡ã½ãããå¼ã³åºãæ¹æ³ã試ãããã¨ãããã¾ãããSpring boogãããã ã¨Byte Buddyã¨ããã使ã£ã¦ãããããã®ã§ããããã¤ãã³ã¼ãã®é»éè¡ã«æãåºãã®ã¯ã¡ãã£ã¨ãã¨ãããã¨ã§ãä»åã¯å¦çæ¬ä½ã¯ã©ã ãå¼ã¨ãã¦è¨è¿°ããããããªãã¡ãã£ã¦ãã¬ã¼ã æ ãæä¾ããinvoker()ã¡ã½ãããçµç±ãã¦å¼ã³åºããã¨ã§ãå¼ã³åºãã«ãã¬ã¼ã ã¯ã¼ã¯ãä»å ¥ãããããã«ãã¾ãããããã§ãã°ã¯åºãã¾ãã(ç¾ç¶ãå¼æ°ãåºãã¦ã¾ãããâ¦â¦)ãServiceã®é層ã§ã¯ãã©ã³ã¶ã¯ã·ã§ã³ã®æ©è½ãæä¾ãããããã¦ãã¾ãã
ãã¨ãã°ä»¥ä¸ã¯ãã°ã¤ã³ç»é¢ã®Controllerã§ããLoginControllerã®ç»é¢è¡¨ç¤ºã¡ã½ããshowPage()ãããLoginServiceã®showPage()ãå¼ã³åºãã¨ããã§ãã
public static RoutingResult showPage(ControllerInvoker invoker, String path) { return invoker.invoke((context) -> { RoutingResult result = LoginService.showPage(context.getServiceInvoker()); return result; }); }
Controllerã«ã¯å¼æ°ã§ControllerInvokerã渡ããã¦ããããã®ã¡ã½ããinvoke()ã«ãControllerã®å¦çãã©ã ãå¼ã§æ¸¡ãã¦ãã¾ããinvoke()ãå¦çæ¬ä½ãå¼ã³åºãã¨ãã«å¼æ°ã¨ãã¦contextã渡ãã¦ãããServiceç¨ã®invokerã¯ãã®contextããåå¾ããã®ã§ãinvoke()ãçµç±ããã«Serviceãå¼ã³åºããã¨ã¯ã§ããªãããã«ãªã£ã¦ãã¾ã(Serviceã«ã¯Serviceç¨ã®contextããDbAccessã«ã¯DbAccessç¨ã®contextããããããããªãã¨å¦çã«å°ã)ã
å¦çæ¬ä½ã®ã¤ã³ãã³ããã²ã¨ã¤æ·±ããªãã¾ãããããã¯ã¾ãåé¡ã«ã¯ãªããªããã¨æã£ã¦ãã¾ãã
ãã¹ãæã®ã¹ã¿ãã§ã¯å¦çæ¬ä½ãåãããªãã¨ãããããããã¨ãã§ãããã§ããããã®ãããã¯ã¾ã 試ãã¦ãã¾ããã
Controllerã¯ã1åã®HTTPãªã¯ã¨ã¹ãã«å¯¾ãã¦1åå¼ã³åºãããServiceã«å¦çã渡ãåã®åæããè¡ãã¾ãã
åè¿°ã®ããã«ãinvoke()ã§å¦çãå¼ã³åºãã¨contextãæã«å ¥ãã¾ããããã®context(åã¯RequestContext)ã¯ä»¥ä¸ã®ãããªã¤ã³ã¿ãã§ã¼ã¹ã«ãªã£ã¦ãã¾ãã
public interface RequestContext { ServiceInvoker getServiceInvoker(); HttpServletRequest getServletRequest(); HttpServletResponse getServletResponse(); Logger getLogger(); }
ãã®ããã«Controllerç¨ã®contextããHttpServletRequestãHttpServletResponseãå ¥æã§ãã¾ãããããã¯ã¤ã¾ãHttpServletRequestãHttpServletResponseã使ããããªå¦çã¯Controllerã®é層ã§æ¸ã¾ãã¦ãããã¨ãããã¨ãæå³ãã¦ãã¾ãâ»2ã
Serviceã¯Webã¢ããªã±ã¼ã·ã§ã³ã¨ãã¦ã®ãã¸ãã¯ãæ¸ãé層ã§ãã
ããã°ã®ãããªã¢ããªã±ã¼ã·ã§ã³ã§ã¯ããã¸ãã¯ã¨ããã°ãDBããå¤ãããéãã¦HTMLãçæãããã¨ãã ã¨æãã®ã§ããã®ãããªå½¹å²ãæ ãããã«ãªã£ã¦ãã¾ããServiceã«æ¸¡ãããcontextã§ããServiceContextã®å®ç¾©ã¯ä»¥ä¸ã®éãã
public interface ServiceContext { DbAccessInvoker getDbAccessInvoker(); Path getHtmlTemplateDirectory(); Logger getLogger(); }
getHtmlTemplateDirectory()ã¨ããã¡ã½ããããããããã§HTMLãã³ãã¬ã¼ãã®ãã£ã¬ã¯ããªãåå¾ãã¾ãã
HTMLããã³ãã¬ã¼ãããçæãããã¨ããã®ã¯ãµã¼ããµã¤ãã¬ã³ããªã³ã°ã®Webã¢ããªã±ã¼ã·ã§ã³ã§ã¯å¤§æããå®çªã§ããããã®ãªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã§ã¯ãHTMLã ãã§ããç¨åº¦è¦ãã«å ªããã¬ãã«ã®HTMLããããã®ã¾ã¾ã使ãã¾ãã ãã¨ãã°ãã®ããã°ã®HTMLãã³ãã¬ã¼ãã¯ä»¥ä¸ã«ç½®ãã¦ããã¾ãããããã¨ã¾ã£ããåãHTMLã(ããã¼ç»åãå«ãã¦)ãã®ããã°ãåãããµã¼ãã«ãé ç½®ããã¦ãããServiceã®ä¸ã§jsoupã使ã£ã¦DOMãå¤æ´ãã¦ãå®éã«ãã©ã¦ã¶ã®ç»é¢ã«è¡¨ç¤ºããHTMLãä½ãã¾ãã
ãã®ãããªå½¢ã«ãã¦ããã®ã¯ãããã¶ã¤ãã¨ã®åæ¥ãã®ããã§ãã
Webã¢ããªã±ã¼ã·ã§ã³ãä½ãã¨ããããç¨åº¦è¦æ ãã®ãããè¦æ±ãããå ´åã¯ãããã°ã©ã ã®éçºè ãHTMLãCSSãã´ãªã´ãªæ¸ãã®ã§ã¯ãªããHTMLãCSSã¾ã§ã¯å°éã®ãã¶ã¤ããä½æãããã¨ãããã¾ããã¾ãç§ãå«ããããã°ã©ãã¯ãã¶ã¤ã³ãCSSã®ç´ é¤ããªããã¨ãå¤ãã§ããããã
ããããå ´åãããã¦ã以ä¸ã®ãããªãã¨ã«ãªãã¾ãã
ãããããã¨ãèµ·ããã®ã¯ãä¸è¨ãªã3ã®æ®µéã§ãHTMLãHTMLãªããããã®ã«æ¸ãæãã¦ãã¾ã£ã¦ããããã§ãã
ãã¡ãããããåé¡ã ã¨èãã¦ãã人ã¯ãã¦ãSpring bootã§ä½¿ã£ã¦ãããã³ãã¬ã¼ãã¨ã³ã¸ã³ã§ããThymeleafã§ã¯ã以ä¸ã®ãã¨ãããã£ã¦ãã¾ãã
Thymeleafã®ä¸»ãªç®çã¯ããã³ãã¬ã¼ãã®ä½æã«å¯¾ãã¦åªé ã§ä¿å®æ§ã®é«ãæ¹æ³ãæä¾ãããã¨ã§ãããããå®ç¾ããããã«ãThymeleafã¯ããã¥ã©ã«ãã³ãã¬ã¼ãã¨ããã³ã³ã»ãããæ¡ç¨ãã¦ããããã¶ã¤ã³ãããã¿ã¤ãã¨ãã¦ä½¿ç¨ããããã³ãã¬ã¼ããã¡ã¤ã«ã«å½±é¿ãä¸ãããã¨ãªããã¸ãã¯ãæ³¨å ¥ãããã¨ãã§ãã¾ããããã«ãã£ã¦ããã¶ã¤ã³ã«å¯¾ããã³ãã¥ãã±ã¼ã·ã§ã³ãæ¹åããããã¶ã¤ã³ãã¼ã ã¨éçºãã¼ã ã®ééãåãããã¾ãã
å ·ä½çã«ã©ãæ¸ãã®ããã¨è¦ã¦ã¿ãã¨ããããªæãã
<input type="text" name="userName" value="James Carrot" th:value="${user.name}" />ãã©ã¦ã¶ã¼ã§æ£ãã表示ã§ããã ãã§ãªããï¼ä»»æã§ããï¼valueå±æ§ãæå®ãããã¨ãã§ãã¾ãï¼ãã®å ´åã®âJames Carrotâã®é¨åã§ãï¼ããããã¿ã¤ããéçã«ãã©ã¦ã¶ã¼ã§éããå ´åã«ã¯ãã®å¤ã表示ããããã³ãã¬ã¼ãã¨ãã¦å¦çããå ´åã«ã¯${user.name}ã®è©ä¾¡çµæå¤ã§ç½®ãæãããã¾ãã
ãã®ãããã§ããã¶ã¤ãã¼ã¨ãããããã¼ãå ¨ãåããã¡ã¤ã«ã触ããã¨ãã§ããéçãªãããã¿ã¤ãããã³ãã¬ã¼ãã«å¤æããå´åãåæ¸ãããã¨ãã§ãã¾ãããããã£ããã¨ãå®ç¾ããæ©è½ã®ãã¨ãããã¥ã©ã«ãã³ãã¬ã¼ãã£ã³ã°ã¨å¼ã³ã¾ãã
ãth:ãã§å§ã¾ãå±æ§ã¯ãã©ã¦ã¶ã¯ç¡è¦ããã®ã§ãHTMLã¨ãã¦è¡¨ç¤ºã§ããããã¶ã¤ãããããç¡è¦ããã°ããã¶ã¤ãã¨ããã°ã©ããåãHTMLã触ããã¨ãã§ããââã¨ããã®ã§ãããå®éåé¡ã¨ãã¦ãth:ãã§å§ã¾ãå±æ§ã¯ãã¶ã¤ãã«ã¨ã£ã¦ã¯è¨±å®¹ã§ããªãã¬ãã«ã§éªéã§ãããããããã°ã©ãã«ã¨ã£ã¦ã¯è¡¨ç¤ºã®ããã ãã®valueå±æ§ã¯è¨±å®¹ã§ããªãã¬ãã«ã§éªéã§ãããããth:ãã§å§ã¾ãå±æ§ã®ä¸ã«ã¯ãããªãã«ãããããå¼ãå ¥ããã¨ãããã¾ãããHTML表示ã®ããã ãã®valueå±æ§ã¨ãè¦ç´ å ã®ããã¹ãã¨ãã¯ãããªãã«é·ããã®ã§ããHTMLãªãã¦ãã¨ãã¨ãããªã«å¯èªæ§ããããã®ã§ã¯ãªãã®ã«ãããã«ãããªã«ä½è¨ãªãã®ãå ¥ãããããªãè¾ãã®ã§ã¯ãªãã§ããããã
ããã«ãHTMLã«ã¯ããè¿ããå«ã¾ãã¾ãããã¨ãã°ãã®ããã°ãªããå·¦ã®ã¨ãªã¢ã«ãææ°è¨äºãã®æ¬ããããããã«ã¯ææ°è¨äºã10件表示ããã¾ãâ»3ã
ãããããã¨ãããããã°ãThymeleafã§ã¯ãth:eachãã使ãããã§ãããããã使ã£ãHTMLããã©ã¦ã¶ã§ç´æ¥éãã¦ããä¸èº«ã¯ã²ã¨ã¤ãã表示ããã¾ãããããã¶ã¤ã³ãã¼ã ã¨éçºãã¼ã ã®ééãåãããã¾ããã¨ããã£ã¦ãããªããããã§ã¯ããããªãã§ãè©æ¬ºã ã¨æãã®ã§ãä½ãããæ¹ã¯ããã®ã ã¨æãã¾ããããã¥ã¼ããªã¢ã«ã®ç¯å²ã§ã¯è¼ã£ã¦ããªãããã§ãã
ä»åã®ãªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã§ã¯ãéåã¨ãªãã®ã¯ããHTMLãªããããã®ãã§ã¯ãªãçæ£ã®HTMLã§ããã¾ããã¶ã¤ããä¸ãã¦ãããã®ã«ãããã°ã©ãå´ã§idå±æ§ã¨ãclasså±æ§ã¨ãã足ãå¿ è¦ã¯ããã¨æãã¾ããããã®ç¨åº¦ã®ä¿®æ£ã§ãã¿ã¾ãããããªããã¶ã¤ãã§ã触ãããããã¤ã§ãææ°ã®ç»é¢ãHTMLã ãã§è¦ããã¨ãã§ããã®ã§ã¯ãªãã§ããããã
ããè¿ããããå ´åããã®ããã°ã§ã¯ãæåã®ã²ã¨ã¤ã®è¦ç´ ãããã¦ããã¦ãã£ãã親è¦ç´ ã®ä¸èº«ãå ¨é¨æ¶ããããã¦ãããæåã®è¦ç´ ãclone()ã§è¤è£½ãã¦ãã®ä¸èº«ãæ¸ãæãã¦è¦ªè¦ç´ ã«è©°ãã¦ãããã¨ããæ¹æ³ã(åºæ¬çã«ã¯)åã£ã¦ãã¾ããåºæ¬çã«ã¯ãã¨ããããã«ã¯ããã§ãªãã¨ããããã£ã¦ãç°¡åãªè¦ç´ ãªãJavaå´ã§ã¼ãããçæãã¦ãã¾ã£ã¦ããã¨ãããããã¾ããããããã¨ããã®ãã¶ã¤ã³ãHTMLå´ã§å¾ããå¤ãã£ãã追å¾ããªãããã§ãããã°ã©ãå´ãããããã¨ããã«æ°ãä»ãã¦ã³ã¼ãã£ã³ã°ããå¿ è¦ã¯ããã¾ã(ã¤ã¾ããå½ã®ç§ãããããã¦ããããã§ãã)ã
ãããã¦jsoupã§DOMãä¿®æ£ããããHTMLç»é¢ã表示ããServiceã¯ããã®DOMã®ã¤ã³ã¹ã¿ã³ã¹ããã¨ã«DocumentResultã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ãçæãã¦è¿å´ãã¾ãããããControllerçµç±ã§Routerã«æ»ããã¦ããã¨ã¯ãã¬ã¼ã ã¯ã¼ã¯ããã©ã¦ã¶ã«HTMLãè¿å´ãã¦ããã¾ãã
Webã¢ããªã±ã¼ã·ã§ã³ãè¿ãã®ã¯HTMLã ãã§ã¯ãªãã®ã§ããªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã«ã¯ç¾æç¹ã§ä»¥ä¸ã®XxxxxResultã¯ã©ã¹ãããã¾ãããããã¯ãã¹ã¦RoutingResultã®ãµãã¯ã©ã¹ã§ãã
ã¯ã©ã¹å | ç¨é |
---|---|
DocumentResult | HTMLææ¸ãè¿ãã¾ãã |
ImageFileResult | ç»åãã¡ã¤ã«ã®ãã¹ããã¨ã«ãç»åãè¿ãã¾ãã |
JsonResult | JSONãè¿ãã¾ãã |
RedirectResult | ãªãã¤ã¬ã¯ãããã¾ãã |
å ·ä½çãªServiceã®å®è£ ã¨ãã¦ã¯ãããã°è¨äºãã¼ã¸(æ¥å¥ãæå¥ãã¼ã¸ãå«ã)ãã¬ã³ããªã³ã°ããShowPostService.javaãè¦ãã®ããããã¨æãã¾ãããã®ä¸ã®renderXxx()ã¨ããã¡ã½ããã§ãDOMãããã£ã¦ã¬ã³ããªã³ã°ãè¡ã£ã¦ãã¾ãã
ââå®éã®ã¨ãããHTMLãã¬ã³ããªã³ã°ããã®ãªããth:eachã ã®th:ifã ã®ããã°ã©ãã³ã°è¨èªã¢ããã¿ãããªæ°ããªææ³ãè¦ãããããã使ãæ £ããã¡ããã¨ããããã°ã©ãã³ã°è¨èªã§ã´ãªã´ãªæ¸ãæ¹ããé常ã®ããã°ã©ãã³ã°ãã¯ããã¯ãä»ã¾ã§éã使ããã®ã§ãã£ã½ã©æ¥½ãªã®ã§ã¯ãã¨ç§ã¯æãã¾ãã
DbAccessã®å±¤ã¯ãã®åã®éãDBã«ã¢ã¯ã»ã¹ãã層ã§ãã
DbAccessã«æ¸¡ãããcontextã§ããDbAccessContextã®å®ç¾©ã¯ä»¥ä¸ã®éãã
public interface DbAccessContext { Connection getConnection(); Logger getLogger(); }
è¦ã¦ã®éããããã§java.sql.Connectionãåå¾ã§ãã¾ããç¾ç¶ããªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã§ã¯ãã²ã¨ã¤ã®ã¢ããªã±ã¼ã·ã§ã³ãè¤æ°ã®Connectionã使ããã¨ã¯æ³å®ãã¦ãã¾ãã(ãããã¡ãªã±ã¼ã¹ã ã¨ã¯æãã¾ãã)ã
Connectionãæã«å ¥ãããããã¨ã¯ããã§å ¬éãã¦ããNamedParameterPreparedStatementã使ã£ã¦SQLãæã§æ¸ãã¦ãæ¤ç´¢çµæãããã§å ¬éãã¦ããResultSetMapperã§DTO(Data Transfer Object)ã«è©°ãè¾¼ãã§è¿ãã¾ããDbAccessã®ã¡ã½ããã¯ããã¬ã¼ã ã¯ã¼ã¯ã§ç¯æ£ã§ããããã§ã¯ããã¾ãããã1ã¡ã½ãã1SQLãæ³å®ãã¦ãã¾ãã
å ·ä½çãªå®è£ ã¯BlogPostDbAccess.javaããããè¦ã¦ããã ãã®ããããã¨ã
çµæãæ ¼ç´ããDTOã¯ããã¨ãã°ãã®BlogPostDto.javaã®ããã«ãTableColumnã¢ããã¼ã·ã§ã³ã§SQLä¸ã®åå(å¥åã§ããã)ãæå®ããã¦ãã¾ããããã使ã£ã¦æ¤ç´¢çµæãDTOã«ãããã³ã°ããããã§ãã
SQLã¯ããã¦ãJOINããã§ããããããDTOã¯DBä¸ã®ãã¼ãã«ã¨ã¯ãã¾ãä¸è´ãããç¨éã«å¿ãã¦ä½ããã¨ã«ãªãã¾ãã
ããç¨åº¦ã®Webã¢ããªã±ã¼ã·ã§ã³ã¨ããªãã°ãSQLãæããã¨ãã¯ããã¦ãJOINãããããããã§ããã¼ãã«ãã¨ã«SELECTããã¦é¢é£ãã¼ãã«ãã¾ãã²ã¨ã¤ãã¤SELECTãã¦æ§è½ãæªããªã£ã¦ãããããN+1åé¡ãã¨ã大ãããªååãä»ãã¦çé¢ç®ã«è«ãã¦ã人ãã¡ã£ã¦ãããããããã¨ãã¢ãã«ãã ã£ãããããã ã£ãã£ããã
Webã¢ããªã±ã¼ã·ã§ã³ãã¬ã¼ã ã¯ã¼ã¯ã¨ããã¨ãããã大ãããªä»çµã¿ãããã¾ããããããªãªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ã§ããã¾ãããããå®ç¨çãªããã°ã©ã ã¯ä½ãããã®ã§ãã
ä»åã®ããã°ã¯ãããããå人ãä½æã§ä½ã£ããã®ã§ãã®ã§ãããããããè¦æ¨¡ã§ããªãã§ãã(ããã§ããJavaã ãã§ããã¬ã¼ã ã¯ã¼ã¯è¾¼ã¿ã§ã6000è¡è¿ãã«ã¯ãªã£ãã®ãâ¦â¦)ããã£ã¨æ©è½ãå¢ããã¦å·¨å¤§ãªã¢ããªã«ãªã£ãã¨ããã§ããã¬ã¼ã ã¯ã¼ã¯èªä½ã¯ãã®ã¾ã¾ã§è¡ããããªæ°ããã¦ãã¾ãã
ã ããã£ã¦ãã®ãªãã¡ãã£ã¦ãã¬ã¼ã ã¯ã¼ã¯ãã¿ãªãã使ã£ã¦ãã ãããã¨ã¯ãã¾ãæãã¾ããã(使ããããã°ãèªç±ã«ã©ãããã©ã¤ã»ã³ã¹ã¯NYSLã§ããã§ã)ããããªæãã§ã¿ããªèªåã®ãªã¬ãªã¬ãã¬ã¼ã ã¯ã¼ã¯ãä½ãããããããã®ãã¨ã¯æã£ã¦ãã¾ãã
注æ!!) ããã«ãã¦ãã»ãã¥ãªãã£ã¾ããã¯ãã¾ãèªä½ãã¹ãã§ã¯ãªãã¨ã¯æã£ã¦ãã¦ããã®ããã°ã§ã¯ãã°ã¤ã³ã¨ãCSRF対çããããèªä½ãã¦ããã®ã¯æ¬æ¥ã¯ãã¾ããããããªãã®ããããã¾ãããä¸å ·åãããã°æãã¦ãã ãã/çä¼¼ããã®ãªãèªå·±è²¬ä»»ã§ã
ãã®ãã¬ã¼ã ã¯ã¼ã¯ã§ã¯Controller, Service, DbAccessãã¹ã¦staticã¡ã½ããã§æ¸ãã¾ããããã¦ãDbAccessã®é層ã§ã¯ãSQLãç´æ¥æ¸ãã¾ãã
ããã§ã¾ããããã¦ãã®Webã¢ããªã¯ä½ããã¨æãã¾ããServiceã¾ããã§å ±éã®ãã¸ãã¯ãããããåºã¦ãããã§ããããã®ãããã¯æããã®ããã°ã©ãã®ä¼å®¶ã®å®åãé¢æ°åã§å ±æã§ããã§ãããâ»5ã
ã ã¨ããã°ãçµå±ã®ã¨ãããstaticããããã¨SQLãããããæ£ããã£ãããããªãã§ãããã
以ä¸ããã®ããã°ã®URLã®ä¸è¦§ã§ããåé ã®ã/blog/ãé¨åã¯ãã¢ããªã±ã¼ã·ã§ã³ã®ãã£ã¬ã¯ããªãæãã¾ã(ãã£ã¦ãwarãã¡ã¤ã«ã®ååãå¤ããã°å¥ã®ååã«ãªãã¾ã)ã
åºå | ã¡ã½ãã | URL | é·ç§»å | ã¯ã¨ãªã¹ããªã³ã° |
---|---|---|---|---|
表ç»é¢ | GET | /blog/{ããã°ID} | ããã°ããã | page..ãã¼ã¸ã³ã°ã®éã®ãã¼ã¸çªå· |
GET | /blog/{ããã°ID}/{YYYYMM] | æå¥è¡¨ç¤º | page..ãã¼ã¸ã³ã°ã®éã®ãã¼ã¸çªå· | |
GET | /blog/{ããã°ID}/{YYYYMMDD} | æ¥å¥è¡¨ç¤º | page..ãã¼ã¸ã³ã°ã®éã®ãã¼ã¸çªå· | |
GET | /blog/{ããã°ID}/post/{ããã°ãã¹ãID} | è¨äºåå¥è¡¨ç¤º | â | |
表ç»é¢API | GET | /blog/{ããã°ID}/api/getimage/{ããã°ãã¹ãID}/{ç»åID} | ç»ååå¾(縮å°ç»å) | â |
GET | /blog/{ããã°ID}/api/getorgsizeimage/{ããã°ãã¹ãID}/{ç»åID} | ç»ååå¾(ãªãªã¸ãã«ãµã¤ãºç»å) | â | |
GET | /blog/{ããã°ID}/api/getprofileimage | ãããã£ã¼ã«ç»ååå¾ | â | |
GET | /blog/{ããã°ID}/api/getpostcounteachday | æ¥å¥ã®æ稿æ°åå¾(ã«ã¬ã³ãã¼ç¨) | month..対象æ(YYYYMMå½¢å¼) | |
GET | /blog/{ããã°ID}/rss | RSSåå¾ | â | |
POST | /blog/{ããã°ID}/api/postcomment | ã³ã¡ã³ãæ稿 | â | |
管çç»é¢ | GET | /blog/login | ãã°ã¤ã³ç»é¢è¡¨ç¤º | â |
GET | /blog//blog_list | ããã°ä¸è¦§ç»é¢ | â | |
GET | /blog/{ããã°ID}/admin | ããã°ç®¡çç»é¢ | â | |
GET | /blog/{ããã°ID}/previewpost/{ããã°ãã¹ãID} | ããã°è¨äºãã¬ãã¥ã¼ç»é¢ | â | |
管çç»é¢API | GET | /blog/api/checkpassword | ãã¹ã¯ã¼ãç¢ºèª | â |
POST | /blog/api/dologin | ãã°ã¤ã³å®æ½ | â | |
GET | /blog/api/getimageadmin/{ç»åID} | 管çç»é¢ç¨ç»ååå¾ | â | |
POST | /blog/{ããã°ID}/api/postimages | ç»åæ稿 | â | |
POST | /blog/{ããã°ID}/api/postarticle | ããã°è¨äºæ稿 | â |
DDLããã®ã¾ã¾è²¼ã£ã¦ããã¾ãã
-- ããã°ãæ稿ããã¦ã¼ã¶ãä¿æããã create table users ( user_id varchar(32) primary key, password varchar(256) not null, mail_address varchar(32), created_at timestamp not null, updated_at timestamp not null ); -- ã¦ã¼ã¶ãã¨ã«ããããã£ã¼ã«ãä¿æããã create table profiles ( user_id varchar(32) primary key, nickname varchar(32) not null, image_path varchar(64), about_me text not null, created_at timestamp not null, updated_at timestamp not null ); -- ããã°(è¨äºã§ã¯ãªããããã°å ¨ä½)ã®æ å ±ãä¿æããã -- ã²ã¨ãã®ã¦ã¼ã¶ã¯è¤æ°ã®ããã°ãæã¦ãã create table blogs ( blog_id varchar(32) primary key, title varchar(64) not null, description text not null, owner_user varchar(32) not null, created_at timestamp not null, updated_at timestamp not null ); -- ããã°è¨äºã®æ å ±ãä¿æããã create table blog_posts ( blog_post_id integer primary key, blog_id varchar(32) not null, title varchar(64) not null, posted_date timestamp not null, status integer not null, -- 1..ä¸æ¸ãã2..å ¬é created_at timestamp not null, updated_at timestamp not null ); -- ããã°è¨äºã®ã»ã¯ã·ã§ã³ãä¿æãã -- è¨äºä¿®æ£æã«ã¯ãã¹ã¦æ¶ãã¦ä½ãç´ã create table blog_post_sections ( blog_post_id integer, section_seq integer, body text not null, created_at timestamp not null, updated_at timestamp not null, primary key (blog_post_id, section_seq) ); -- ããã°è¨äºã®åçæ å ±ãä¿æãã -- blog_post_idã¯è¨äºãæ稿ããã¾ã§æ±ºã¾ãããåçã¯æ稿ãã¿ã³ãæ¼ãåã« -- ã¢ãããã¼ããããã®ã§ãblog_post_id, display_order, captionã¯è¨äºã -- æ稿ãããã¾ã§ã¯NULLã create table photos ( photo_id integer primary key, blog_id varchar(32) not null, blog_post_id integer, section_number integer, path varchar(64) not null, display_order integer, caption text, created_at timestamp not null, updated_at timestamp not null ); -- ããã°è¨äºã«ä»ãã³ã¡ã³ãã create table blog_post_comments ( blog_post_id integer not null, comment_id integer not null, poster_id varchar(32), poster_name varchar(32) not null, message text not null, created_at timestamp not null, updated_at timestamp not null, primary key (blog_post_id, comment_id) ); -- photo_idãçæããã·ã¼ã±ã³ã¹ãå ¨ä½ã§é£çªã create sequence photo_sequence; -- blog_post_idãçæããã·ã¼ã±ã³ã¹ããããå ¨ä½ã§é£çªã create sequence blog_post_sequence;
å ¬éæ¥: 2024/10/27
ä¸å ·åçããã¾ããããæ²ç¤ºæ¿ããããã°ã®ã³ã¡ã³ãæ¬ã«ãé£çµ¡é¡ãã¾ãã
ã²ã¨ã¤å | ã²ã¨ã¤å¾ | ã²ã¨ã¤ä¸ã®ãã¼ã¸ã¸æ»ã | ããããã¼ã¸ã¸æ»ã