[2023.01.26] 개발자 교육 87일 차 : 강의-JPA&Spring Security, API 활용 학습 [구디 아카데미]

DaramGee·2024년 1월 26일
0

강의 내용

라이브러리 활용(실습파일 : springDemo2)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>  
<html lang='en'>  
<head>  
  <meta charset='utf-8' />  
  <script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js'></script>  
  <script>  
  
    document.addEventListener('DOMContentLoaded', function() {  
      console.log('DomContentLoaded');  
      const calendarEl = document.getElementById('calendar');  
      const calendar = new FullCalendar.Calendar(calendarEl, {  
        initialView: 'dayGridMonth',  
        events:[  
          {  
            "id": "common001",  
            "title": "휴가",  
            "start": "2024-01-02",  
            "end": "2024-01-05",  
            "allDay": true,  
            "backgroundColor":"pink",  
            "textColor":"black",  
            "extendedProps": {  
              "comment": "쉼"  
            }  
          },  
          {  
            "id": "common001",  
            "title": "글라스",  
            "start": "2024-01-26",  
            "end": "2024-01-26",  
            "allDay": true,  
            "backgroundColor":"lightblue",  
            "textColor":"black",  
            "extendedProps": {  
              "comment": "쉼"  
            }  
          },  
          {  
            "id": "common001",  
            "title": "산책가기",  
            "start": "2024-01-27",  
            "end": "2024-01-27",  
            "allDay": true,  
            "backgroundColor":"lightyellow",  
            "textColor":"black",  
            "extendedProps": {  
              "comment": "쉼"  
            }  
          }  
        ]  
      });  
      calendar.render();  
    });  
  
  </script>  
</head>  
<body>  
<div id='calendar'></div>  
</body>  
</html>
  • 2단계 : jQuery cdn으로 사용하기(schedule2.jsp)

  • jQuery라이브러리 불러와서 js코드 간편하게 작성
  • 풀캘린더 사용시 비동기처리를 위해 ajax사용 이를 간편하게 사용할 수 있게 됨 '$.ajax' 부분
<%@ page contentType="text/html;charset=UTF-8" language="java" %>  
<html lang='en'>  
<head>  
  <meta charset='utf-8' />  
  <script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js'></script>  
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>  
  <script>  
  
    document.addEventListener('DOMContentLoaded', function() {  
      console.log('DomContentLoaded');  
      const calendarEl = document.getElementById('calendar');  
      const calendar = new FullCalendar.Calendar(calendarEl, {  
        initialView: 'dayGridMonth',  
        events:function (){  
          console.log('test');  
          $.ajax({  
            url:'./data1.json',  
            type:'get',  
            dataType:'json',  
            success:function(res){  
              console.log(res);  
              // console.log(JSON.stringify(res)); //json 형식  
            }  
          })  
        }  
      });  
      calendar.render();  
    });  
  
  </script>  
</head>  
<body>  
<div id='calendar'></div>  
</body>  
</html>  
  • 3단계 : 클래스 설계하여 캘린더 처리(schedule3.jsp)

  • json 자료형태를 자료구조의 형태로 전환하는 것 필요
  • 사이트 추천(https://www.jsonschema2pojo.org/)
  • 해당 데이터 json 입력하여 전환하는 Preview 확인해서 자료구조 넣는 클래스 설계시 활용 가능
  • 방식 : 데이터자료 넣기 -> JSON을 GSON으로 jakarta.validation 체크->preview 클릭


  • Memo.java -> 변환된 내용 참고하여 해당하는 변수를 처리할 수 있는 클래스 생성
package com.example.demo;  
  
import lombok.Data;  
  
@Data  //getter, setter 지원 -> 따로 쓰지 않아도 됨.   
public class Memo {  
	//사용할 데이터만 변수로 지정하기 
    private String id;  
    private String title;  
    private String start;  
    private String end;  
    private Boolean allDay;  
    private String backgroundColor;  
    private String textColor;  
    private ExtendedProps extendedProps;  
  
    //내부 클래스  
    class ExtendedProps{  
        private String comment;  
    }  
}
  • ScheduleController.java -> 스케쥴 조회 클래스
@RestController  
@RequestMapping("/cal/*")  
public class ScheduleController {  
    Logger logger = LoggerFactory.getLogger(ScheduleController.class);  
    @GetMapping("scheduleList")  
    public String scheduleList(){  
        logger.info("scheduleList");  
        List<Map<String, Object>> mList = new ArrayList<>();  
        Map<String, Object> rmap = new HashMap<>();  
        rmap.put("title","휴가");  
        rmap.put("start","2024-01-28");  
        rmap.put("end","2024-01-29");  
        rmap.put("backgroundColor","lightblue");  
        rmap.put("textColor","black");  
        mList.add(rmap);  
        rmap = new HashMap<>();  
        rmap.put("title","시험신청");  
        rmap.put("start","2024-01-25");  
        rmap.put("textColor","black");  
        rmap.put("end","2024-01-25");  
        rmap.put("backgroundColor","pink");  
        mList.add(rmap);  
        rmap = new HashMap<>();  
        rmap.put("title","수영");  
        rmap.put("textColor","black");  
        rmap.put("start","2024-01-24");  
        rmap.put("end","2024-01-24");  
        rmap.put("backgroundColor","lightgreen");  
        mList.add(rmap);  
        Gson g = new Gson();  
        String temp = g.toJson(mList);  
        return temp;  
    }  
}

그룹웨어에서 사용예정이어서 연습하고 있던 Fullcalendar를 학습해서 좋았음. 데이터 타입을 맞춰서 넣어줘야 하는 부분, 단순히 상수값이 아니라 입력값을 데이터에 넣어 그 데이터가 표현되도록 하는 처리를 연습해보자.

![[Pasted image 20240126110624.png]]


  • fetch 로 대신 사용하기(schedule4.jsp)

ajax와 fetch 뭐가 다르지? 둘 다 웹개발시 서버통신을 위해 사용되는 도구인데 fetch를 더 많이 쓴다고 하는데?
ajax는 복잡하고 세밀한 설정 필요, 상태변화감지, CORS 자동처리 못 하는 등 세세한 설정이 필요하다.
반면, fetch는 Promise 사용하여 더 간결하게 사용가능, CORS 자동처리되는 특성이 있다. 상황에 맞게 사용한다.
한번 수업에서 학습한 것을 바탕으로 fetch로 처리해보자!!!

<%@ page contentType="text/html;charset=UTF-8" language="java" %>  
<html lang='en'>  
<head>  
  <meta charset='utf-8' />  
  <script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js'></script>  
  <script>  
  
    document.addEventListener('DOMContentLoaded', function() {  
      console.log('DomContentLoaded');  
      const calendarEl = document.getElementById('calendar');  
      const calendar = new FullCalendar.Calendar(calendarEl, {  
        initialView: 'dayGridMonth',  
        eventSources: [{  
          events: function (info, sCallback, fCallback) {  
            console.log('test');  
            fetch('/cal/scheduleList')  
                    .then(response=>{  
                      if(!response.ok){  
                        throw new Error('이벤트 읽어오기 실패');  
                      }  
                      return response.json();  
                    })  
                    .then(data=>{  
                      console.log(data);  
                      sCallback(data);  
                    })  
                    .catch(error=>{  
                      console.log(error);  
                      fCallback(error.message);  
                    })  
          }  
        }]  
      });  
      calendar.render();  
    });  
  </script>  
</head>  
<body>  
<div id='calendar'></div>  
</body>  
</html>

똑같이 실행되는 것을 확인할 수 있었다. 그렇다면 도대체 무엇이 나아졌을까?
우선, 에러처리에 대한 부분도 추가하였지만 fetch가 코드 가독성이 높아졌다는 것을 확인할 수 있었다.
그리고 ajax처럼 별도의 라이브러리를 로드하지 않아도 브라우저에 기본적으로 내장되어있는 API이기 때문에 로딩 속도가 조금 더 빠른 것 같다?(기분탓일수도).
같은 값을 출력하지만 그 방법이 다양하다는 것, 출력에 필요한 값에 대해 계속 고민이 필요한 것이 코딩인 것 같다.


1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset="UTF-8">
5. <title>Basic DataGrid - jQuery EasyUI Demo</title>
6. <link rel="stylesheet" type="text/css" href="../../themes/default/easyui.css">
7. <link rel="stylesheet" type="text/css" href="../../themes/icon.css">
8. <link rel="stylesheet" type="text/css" href="../demo.css">
9. <script type="text/javascript" src="../../jquery.min.js"></script>
10. <script type="text/javascript" src="../../jquery.easyui.min.js"></script>
11. </head>
12. <body>
13. <h2>Basic DataGrid</h2>
14. <p>The DataGrid is created from markup, no JavaScript code needed.</p>
15. <div style="margin:20px 0;"></div>

17. <table class="easyui-datagrid" title="Basic DataGrid" style="width:700px;height:250px"
18. data-options="singleSelect:true,collapsible:true,url:'datagrid_data1.json',method:'get'">
19. <thead>
20. <tr>
21. <th data-options="field:'itemid',width:80">Item ID</th>
22. <th data-options="field:'productid',width:100">Product</th>
23. <th data-options="field:'listprice',width:80,align:'right'">List Price</th>
24. <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>
25. <th data-options="field:'attr1',width:250">Attribute</th>
26. <th data-options="field:'status',width:60,align:'center'">Status</th>
27. </tr>
28. </thead>
29. </table>

31. </body>
32. </html>

Spring Security - JPA version(jpa-security1)

  • 인증과정

  • 참고(https://mangkyu.tistory.com/77)

  • SecurityConfig.java 클래스

  • 작성하는 목적 중 하나는 제어권을 내가 가져오기 위함이다.

  • 시큐리티가 제안하는 화면이 아닌 개발자가 추가한 화면으로 로그인을 진행하려면 화면을 제공해야한다 => Controller 쪽에서 아래 코드처럼 화면을 return해줘야 한다.

@GetMapping("/login")  
public String login() {  
    System.out.println("/login = " + "login");  
    return "login";  
}
  • 화면이 제공되지 않으면? 아래처럼 이슈가 뜸(무한 리디렉션!)

  • SecurityConfig 파일에 아래 코드가 없으면 로그인을 하지 않으면 static 아래의 이미지, css적용을 볼 수 없음.
    - 왜? 여기서 StaticResources는 resources아래 css파일을 말함.
    - 인증문제로 페이지가 열릴 때 정적 내용 적용을 위한 코드
    - 현재 페이지별로 인증을 주고 있는데, 해당 리소스 폴더의 하위 파일들에 대해서는 리소스 파일임을 스프링 시큐리티에게 인지를 시키는 방법임! 이미지가 안나온다? css가 안먹힌다? 해당 내용을 확인해보자

@Bean  
public WebSecurityCustomizer webSecurityCustomizer() {  
    return (web) -> web.ignoring()  
            .requestMatchers(PathRequest.toStaticResources().atCommonLocations());  
}

0개의 댓글