1. Web Application Server WAS
    • includes Web server functionalites and static resource managing

    • Difference between web server and WAS is web server is mainly for static resource while WAS can have application logic

    • Servlet does all except business logic

    • Contact switching cost is when CPU switches between its threads to do tasks.

    • WAS takes care of multi-threading so we developers no need care code about multi-threading

    • Server Side Rendering SSR - generates and renders final HTML page and delivers to client

    • Client Side Rendering CSR - front-end

    • View Template - generates HTML easily

  2. Servlet
    • In resources -> application.properties -> logging.level.org.apache.coyote.http11=debug this helps debugging much better but only in developmenmt server, not actual server cuz it will decrease performance

    • Ctrl + O and select service method with lock sign on it for HttpServlet

    • HTTP메소드에서 GET방식은 value=text 형식으로 보내지고 body가 없기 떄문에 Content-Type은 필요없다. HTTP메소드에 POST, PUT처럼 Body에 data를 보낼때 Content-Type이 필요하다. Content-type describes what kind of data is in body for humans to easily understand.

    • request.getParameterNames gets the key(paramName) while request.getParameter(paramName) gets the value of the key

    • Lombok library implements getter and setter automatically. We just need to add @Getter @Setter on top of the class

    • Instead of directly setting the response erro code by resp.setStatus(200); it is better to resp.setStatus(HttpServletResponse.SC_OK)

  3. Servlet, JSP, MVC

    • Declare singleton
     private static final MemberRepository instance = new MemberRepository();
    
    • Then, create a private constructor to prevent making new instances of it
     private MemberRepository() {
     }
    
    • Lastly, create method getInstance() that always return this singleton instance
     private static MemberRepository getInstance(){
         return instance;
     }
    
    • Once it is singleton, cannot create another instance of it via MemberRepository memberRepository = new MemberRepository(), we should call the already-made single instance via MemberRepository memberRepository = MemberRepository.getInstance()

    • @AfterEach resets whatever test has done to variable after each test for the next test to be done on that variable

    • ol element in HTML lists items with numbers (ordered) like 1,2,3, but ul element lists items with just bullet points (unordered)

    • If status code is grey instead of black, it means it is cached

    • In MVC, Controller(controller logic) is like servlet , View(View logic) is like JSP and Service/Repository does business logic and data

    • Very Important It is the controller that calls the view like

     @WebServlet(name="mvcMemberFormServlet",urlPatterns = "/servlet-mvc/members/new-form")
     public class MvcMemberFormServlet extends HttpServlet {
         @Override
         protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             String viewPath = "/WEB-INF/views/new-form.jsp";
             RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
             dispatcher.forward(request,response);
         }
     }
    
    • In JSP, if action=”/save”, (절대경로 absolute path, better than relative path) URL is localhost:8080/save but if it is action=”save”, (상대경로 relative path) it starts from current directory localhost:8080/servlet-mvc/members/save from localhost:8080/servlet-mvc/members/new-form.jsp

    • /WEB-INF restricts external calling, resource under /WEB-INF always goes through Controller and cannot be called externally like going to URL/some-resource.html <- this is not allowed

    • 서블릿을 컨트롤러로 사용하고, JSP를 뷰로 사용해서 MVC 패턴을 적용해보자. Model은 HttpServletRequest 객체를 사용한다. request는 내부에 데이터 저장소를 가지고 있는데, request.setAttribute() , request.getAttribute() 를 사용하면 데이터를 보관하고, 조회할 수 있다.

    • Instead of saving user variables in request.setAttribute(), store them in a model

    • Since handler is object to be flexibly used in v5 MVC pattern, cast it to a different type via (ControllerV3) handler;

    • either @Controller or @Component with @RequestMapping works

    • Instead of @RequestMapping(value=”/new-form”,method= RequestMethod.GET), do @GetMapping(“/new-form”)

    • @Controller returns View so cannot directly return string but @RestController returns whatever the method type returns like string and inputs directly into HTTP message. Or use @ResponseBody that puts it straight into HTTP message body

     @GetMapping("/mapping/{userId}")
     public String mappingPath(@PathVariable("userId") String data){
         //    public String mappingPath(@PathVariable String userId) <- if variable name is same as @PathVariable
         log.info("mappingPaath userId ={}", data);
         return "ok";
     }
    
    • MultiValueMap is when a key gets several values

    • For @RequestParam(required = false) int age, Integer is object so can be null bunt int cannot be null. SO correct code is @RequestParam(required = false) Integer age. Primitive type (int). Different for @ModelAttribute so search up

    • For @ModelAttribute HelloData helloData, if the object has methods like getUsername(), it has username property.

    • @RequestBody Hellodata hellodata <-cant put your already-made object

    • can add @ResponseBody at the public class level, which adds @ResponseBody for all the classes inside it. ResponseEntity is not affected but there are few tricky exceptions. So just use @RestController, which adds @ResponseBody and @Controlelr together

  4. Webpage

    • In multi-thread environment, cannot use HashMap, use ConcurrentHashMap. cannot use long sequence, use automic long? sequence

    • 2 ways to view static content: either copy absolute path of that html file and google without running server or run server and go to that file location via localhost:etc

    • Only GET and not POST works for viewing static content?

    • @Autowired, which is for Dependency injection, can be omitted if there is only 1 constructor

    • @RequiredArgsConstructor substitutes need to write constructor

    • for th:action=”some_url”, the url can be omitted and it is nesured that url method is POST

    • @ModelAttribute(“item”) Item item automatically adds attribute so no need to add this line model.addAttribute(“item”, item);

    • If no name is assigned with @ModelAttribute, it automatically takes the class that it is going to create object with and make it lowercase and name it like Item -> item or HelloData -> helloData

    • HTTP session is maintaing user’s details until he quits the browser but HTTP request deletes details once that request has been fulfilled

    • th:field= “${item.itemName}” automatates declaration of id=”itemName” name=”itemName” so can delete that

    • hidden field to prevent open from coming out null -> input type=”hidden” name=”_open” value=”_on”/

    • LinkedHashMap guarantees 순서 in which stuff go in, unlike HashMap

    • when naming stuff to be called by Thymeleaf, be careful (e.g. “regions” instead of “region”)

    • th:object=”${item}” so th:field=”*{regions} means item.regions. This th:object can be very far away in form tag and asterisk * can only be used if there is th:object

    • no hidden field needed for radio button, unlike checkbox

    • Even when invalid field for price/quantity is POSTed for new item, parameter for addItem - @ModelAttribute Item item autoamtically adds model.addAttribute(“item”,item) so when redirected, we can see item’s saved variables

    • no need to add bindingResult to model attribute because it is automatically added to view

    • bindingResult.rejectValue(“price”,”range”); the error message “range” follows range.item.price where bindingResult’s object type is item. MessageCodeResolver?

    • WebDataBinder works for that specific controller via boolean supports that checks class

    • @ModelAttribute(“item”) ItemUpdateForm form <-must name it as “item” because template uses “item” and if it is not renamed manually, model.addAttribute(“itemUpdateForm”,item) is done instead of model.addAttribute(“item”,item) so does not render properly unless u change th:object in thymeleaf

    • @RestController automatically adds @ResponseBody so it converts whatever to JSON

    • @ModelAttribute 는 HTTP 요청 파라미터(URL 쿼리 스트링, POST Form)를 다룰 때 사용한다.@RequestBody 는 HTTP Body의 데이터를 객체로 변환할때 사용한다. 주로 API JSON 요청을 다룰 때 사용한다
     List<Member> all = findAll();
     for (Member member : all) {
         if(member.getLoginId().equals(loginId)){
             return Optional.of(member);
         }
     }
     return Optional.empty();
    
     <!-- is same as this stream -->
    
     return findAll().stream()
         .filter(member -> member.getLoginId().equals(loginId))
         .findFirst();
        
    
    • @ModelAttribute(“member”) Member member <- no need to name it “member” cuz ModelAttribute automatically takes lowercase of Member object but in Thymeleaf, IDE sometimes does not detect it so name like this for now

    • Another example:

     public Member login(String loginId, String password){
         Optional<Member> findMemberOptional = memberRepository.findByLoginId(loginId);
         Member member = findMemberOptional.get();
         if(member.getPassword().equals(password)){
             return member;
         } else {
             return null;
         }
    
            
         return memberRepository.findByLoginId(loginId).
                 filter(m -> m.getPassword().equals(password))
                 .orElse(null);
    
    • If no time info ias added to cookie, that cookie becomes session cookie which disappears upon browser exit

    • When there are multiple requests at same time, use ConcurrentHashMap

    • request.getCookies are returned as an array so Cookie[] cookies = request.getCookies();

    • For @RequestMapping, we use HandlerMethod but for static resource, use ResourceHttpRequestHandler

    • log.error does not need “{}”, just “ whatever message”

    • Interceptor cannot set dispatcher type like filter but can include path route in excludePathPatterns

    • use ObjectMapper to convert to JSON for ModelAndView

    • server.error.include-message=always to customise error messages

    • for @ModelAttribute Form form, no need to model.addAttribute cuz automatically added (check this again but it is true)