구글차트 참고(https://developers.google.com/chart/interactive/docs?hl=ko)
jsp 생성 & 그 안에 직접 캘린더에 들어갈 데이터 삽입하여 출력
<%@ 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>
<%@ 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>
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;
}
}
@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]]
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>
작성하는 목적 중 하나는 제어권을 내가 가져오기 위함이다.
시큐리티가 제안하는 화면이 아닌 개발자가 추가한 화면으로 로그인을 진행하려면 화면을 제공해야한다 => 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());
}