TIL - 5월 두번째 주말
쓰면서 배우는 스프링부트
뷰 중복 코드 없애기
- 뷰 중 container(contents)부분만 다르고, head, nav, footer는 코드가 중복됨
- 하나가 변경되면 모든 뷰 파일 코드 변경해야했음
- 템플릿 엔진 기능 중 부분(partial)뷰를 만들고 템플릿 문법으로 include 시키는 기능이 있음
- 아래와 같이 디렉토리를 새로 만들어서 부분 뷰를 만들어놓음
/* /partial/header */
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Colin</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link href="/css/bootstrap.min.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="/css/styles.css" rel="stylesheet">
</head>
- 템플릿엔진 문법을 통해서 뷰 파일에 include 시킴
<!DOCTYPE html>
<html lang="kr">
" " <!-- 코드 삽입을 위해서 " " 처리함 -->
<body>
</body>
</html>
컨트롤러 - 뷰 맵핑 설정
- 뷰 중복 코드를 없애면서 static에 있던 뷰 파일을 templates로 옮겨오게됨
- 그에 따라 컨트롤러 만들고 URL과 맵핑해주는 메소드를 만들어야했음
- 즉, URL 요청 시 뷰 파일만 리턴해주는 아무런 로직없는 메소드가 여러개 만들어짐, 코드만 늘어난 격
- 이를 코드에 만들지않고 설정만 잡아줌으로서 스프링이 내부적으로 만들어줌 : 코드를 깔끔하게 관리할 수 있음
- WebMvcConfigurer를 구현하는 클래스를 만들면 됨 : Springboot 2.0.1.RELEASE 기준(Spring5)
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControlleRegistry registry) {
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
registry.addViewController("/user/form").setViewName("/user/form");
}
}
- 컨트롤러 내 URL - 액션 맵핑되어있는 URL은 할 필요없음 : 이미 만들어져있기때문에 만들면 우선순위 설정에 의해 잘못된 맵핑됨(로직X)
- ViewControllerRegistry : 컨트롤러 - 뷰 맵핑을 간편하게 해주는 객체
@RequestMapping과 @GetMapping, @PostMapping
- 세가지 어노테이션 모두 URL - action을 맵핑하는 용도임
- @RequestMapping : 모든 HTTP 메소드에 대한 처리가 가능한 상태, method value를 지정해주지않으면 모두 통용됨
- 겹치는 url이 있다면 method 지정을 꼭해줘야해서 코드가 오히려 더 많아짐
@Controller
public class UserController {
@RequestMapping(value = "/users", method = "RequestMethod.GET")
public String showAllUser() {
}
@RequestMapping(value = "/users", method = "RequestMethod.POST")
public String create(User user) {
}
}
- @GetMapping, @PostMapping : 특정 HTTP method에 대해서 맵핑할 때 사용
@Controller
public class UserController {
@GetMapping("/users")
public String showAllUser() {
}
@PostMapping("/users")
public String create(User user) {
}
}
@RequestMapping의 올바른 사용
- 컨트롤러의 공통되는 URL을 맵핑해두고, 뒷부분 URL은 각자 액션(메소드)에서 맵핑하도록 하면 중복 제거를 할 수 있음
@Controller
@RequestMapping("/users")
public class UserController {
@PostMapping
public String create(User user) {
}
}
하나의 URL은 하나의 액션(메소드)과만 맵핑되어야함
- 일종의 객체지향 원칙이랄까 : 수정할 부분이 많아지는 것과는 다른 맥락이지만…!
- 하나의 URL이 여러 역할(액션 메소드)을 가진다면 에러가 남, 무엇과 맵핑되어야할지 모르기때문에
form input 개수와 메소드의 파라미터 개수가 일치해야함
- 일치하지않으면 임의의 자리 값에 null이 계속 들어오는 문제가 생김
- input의 name과 bean 객체의 인스턴스를 생성할 때만 인스턴스 변수명이 같아야하고, 메소드로 받을 때는 일단 개수가 같아야함
기타 - 만들면서 현재 문제점이라고 생각되는 것
- 데이터베이스 대신 메모리(ArrayList)에 저장하고 있음
- ArrayList size를 조회한 뒤 size + 1로 id값을 지정해주는데, 만약 중간 게시글이 삭제된다면?
중간 게시글을 삭제한 상태에서 게시글이 생성되었을 때 중복 id값이 지정될 수 있음 : 중복을 피하기위해서는 삭제될 때 모든 게시글의 id값을 -1 해줘야함
- index에 게시글을 뿌려줄 때 최신글이 아래로 가도록 되어있음 : ArrayList에서 순차적으로 뽑아서 <li>를 생성하고 있기때문
보여줄 때마다 id값을 기준으로 내림차순을 해야하는데, add 될 때마다 그 작업을 해줘야할까?
참고자료
리눅스
시그널
- 특정상황이 발생했을 때 운영체제(커널)가 프로세스에게 상황을 알리기위한 방법 : 약속해놓은 상수값
- 시그널 종류(지금까지 본 것만)
시그널 | 발생 상황 |
---|---|
SIGHUP | 터미널 인터페이스에 의해 연결이 단절되었을 때, 터미널과 연결된 프로세스에 전달 |
SIGINT | 인터럽트 키(ctrl + c)가 입력되었을 때 프로세스에 전달 |
- 시그널 핸들러 : 특정한 시그널이 발생했을 때 적절히 처리해주는 메소드
- 기본적으로 시그널에 대한 디폴트 처리 방법이 있음 : 프로세스를 종료시키거나 무시하거나 등
- 프로세스와 사용자는 직접 대화하지않고, 특정 인터페이스를 통해 대화를 함 : 사용자 - 인터페이스 - OS - 프로세스
참고자료
- 구글링, 유튜브 검색
알고리즘
- 하루 한 문제라도 꾸준하게 풀자
[boj] Q1110
- 문제 읽기 연습됨(N과 num 할당시기), 자리수 문제(나누기, 나머지 연산 연습)
[bog] Q4344
- int 타입 두 변수를 가지고 double 타입 결과를 구할 때 연산 전에 하나의 변수라도 double로 캐스팅하고 연산해야함
- 테스트 케이스수 말고 1번의 테스트에서 데이터 개수에 따라 연산 횟수가 몇번 이뤄지는지가 중요