POJO
특정 프레임워크, 라이브러리, 기술에 종속, 의존하지 않고 순수 자바 객체만을 사용해서 만든 자바 프로그램이다.
스프링은 POJO를 따르는 프레임워크로 주요 기술인 IoC/DI, AOP, PSA는 애플리케이션을 POJO로 개발할 수 있게 해주는 기술이다.
POJO의 규칙
- 프레임 워크, 특정 환경과 규약에 종속되지 않는다.
- Spring,Hibernate와 같은 프레임워크에 의존하지 않는 객체
- 특정 프레임워크나 라이브러리의 클래스를 상속받거나 인터페이스를 구현하지 않는다.
- 간단한 구조
- 필요한 필드 , 생성자, Getter/Setter 메서드만 포함
- SRP 단일 책임 원칙을 지키는 클래스여야한다.
POJO의 장점
- 특정 환경이나 기술에 종속적이지 않아 재사용이 가능, 확장 가능한 유연한 코드를 작성할 수 있음.
- 특정 기술이나 환경에 종속적이지 않아 테스트가 단순해짐.
- 객체지향적인 설계를 제한 없이 적용할 수 있다.
SPRING에서 POJO를 적용한 예
spring의 어노테이션은 강한 의존성을 만들지 않고 Spring이 어노테이션을 읽고 처리하기 때문에 POJO를 위반하지 않는다.
Spring이 POJO를 관리하는 코드
import org.springframework.stereotype.Service;
@Service // Spring 컨테이너에 ProductService를 빈으로 등록
public class ProductService {
public String getProductName() {
return "Laptop";
}
}
Spring 컨테이너에서 POJO를 사용하는 코드
- Spring 컨테이너를 통해 객체를 생성하고 의존성을 주입
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class ProductController {
private final ProductService productService;
@Autowired
public ProductController(ProductService productService) {
this.productService = productService;
}
public void printProductName() {
System.out.println(productService.getProductName());
}
}
Spring 컨테이너에서 POJO를 사용하는 코드
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class ProductController {
private final ProductService productService;
@Autowired
public ProductController(ProductService productService) {
this.productService = productService;
}
public void printProductName() {
System.out.println(productService.getProductName());
}
}
@Controller
spring 에게 해당 어노테이션이 붙은 클래스가 컨트롤러임을 선언하여 반환하는 값은 뷰 이름이나 데이터를 반환한다.
@RequestMapping
method에 요청할 방식 get, post를 정하고, path에 경로를 적는다.
@RequestMapping(method = RequestMethod.GET, path = "/hello-world")
public String receiveRequestFormBrowser() {
System.out.println("hello");
return "index";
}
@GetMapping
@RequestMapping의 Get방식을 합쳐놓은게 @GetMapping
@GetMapping("/print")
public void receiveGetRequest(HttpServletResponse response) throws IOException {
// 한국어가 ??로 나오고 인식을 못함 ?? 123 hello가 출력됨
PrintWriter writer = response.getWriter();
writer.println("할로 123 hello"); // ?? 123 hello
response.setContentType("text/html;charset=UTF-8"); //이걸 쓰고 아래와 같이 쓰면 한국어 사용가능
PrintWriter writer = response.getWriter();
writer.println("할로 123 hello"); // 할로 123 hello
}
@ResponseBody
return 값에 html이 아니라 뷰렌더링 없이 리턴값을 직접 페이지에 랜더링하여 전송하는 어노테이션이다.
@ResponseBody
@GetMapping("/print2")
public String receive2() {
return "안녕하세요";
}
Thymeleaf
html에 java코드를 사용하기 위해 java코드를 html로 변환해주는 템플릿 엔진
Thymeleaf는 HTML 속성에 th: 접두사를 붙여 동작을 정의합니다.
속성 설명
| th:text | 텍스트를 출력 (HTML 이스케이프 처리) |
| th:utext | 텍스트를 출력 (HTML 이스케이프 미처리) |
| th:href | 링크의 href 속성을 동적으로 설정 |
| th:src | 이미지 등의 src 속성을 동적으로 설정 |
| th:alt | 이미지 태그의 alt 속성을 동적으로 설정 |
| th:action | 폼 태그의 action 속성을 동적으로 설정 |
| th:onclick | 클릭 이벤트 속성 설정 |
| th:value | 입력 필드의 기본값 설정 |
| th:style | style 속성을 동적으로 설정 |
| th:class | class 속성을 동적으로 설정 |
| th:if | 조건에 따라 렌더링 (True일 때만 출력) |
| th:unless | 조건에 따라 렌더링 (False일 때만 출력) |
| th:each | 반복문 처리 |
| th:object | 폼의 기본 객체 설정 |
| th:field | 폼 필드 바인딩 |
| th:remove | 요소를 제거 (all, tag, body 등 옵션) |
Thymeleaf 문법
Controller에서 전달받은 값을 기준으로 사용가능
ex)
@Controller
public class TestController {
@GetMapping("/test")
public String test(Model model) {
model.addAttribute("msg", null); // null 값 전달
return "test";
}
}
Thymeleaf에서 변수를 사용할 때는 ${}를 사용 ${variable}: 현재 컨텍스트에 있는 변수 출력 @{url}: URL을 동적으로 생성
- th:text = "${전달 받은 메시지 값}" <div th:text="${msg}">기본값</div> → 기본값과 상관없이 msg출력
- 만약 msg값이 null 이라면 그냥 기본 div 태그가 출력
<p th:text="${name}">Default Name</p> <!-- name 변수 값 출력 -->
<a th:href="@{/home}">Home</a> <!-- /home URL 생성 -->
- th:href = “@{url}” : url 생성 방식
정적 url
<a th:href="@{/home}">Home</a>
동적 url (경로 변수)
<a th:href="@{/user/{id}(id=${userId})}">User Profile</
쿼리 파라미터
<a th:href="@{/search(query=${searchTerm})}">Search</a>
- th:each = "item :${items}" : 리스트나 배열을 순회하여 렌더링
<ul>
<li th:each="item : ${items}" th:text="${item}">Sample Item</li>
</ul>
- th:if = "${user ≠ null}" : 널이 아니면 이 태그가 출력
- th:unless = "${user ≠ null}" : 널이면 이 태그가 출력 unless는 else처럼 사용하려면 else와 다르게 if와 같은조건을 한번 더 입력해줘야함
<p th:if="${user.isAdmin}">관리자</p>
<p th:unless="${user.isAdmin}">일반 사용자</p>
- th: fragment =”” : 웹페이지에 메뉴 탭이나 네비바와 같이 공통으로 반복되는 영역을 정의할 때 사용 특히 header와 footer에 유용
<div th:fragment="header">
<h1>Header Content</h1>
</div>
정의한 fragement를th:include 또는 th:replace로 가져온다.
<div th:include="fragments.html :: header"></div>
<div th:replace="fragments.html :: header"></div>
th:include: HTML 내부에 삽입. th:replace: 기존 HTML을 대체.

- form th:object="${user}" : form 태크에서 데이터를 보낼 때 object에서 지정한 객체에 값을 담아 전달한다.

출처 : 오르미 백엔드 부트캠프
- th:inline : Javascript , css 코드 안에서 데이터를 동적으로 삽입
<script th:inline="javascript">
var username = [[${user.name}]]; // Alice
var items = [[${items}]]; // ["Item1", "Item2", "Item3"]
</script>
CSR, SSR (CS지식)
CSR (클라이언트 사이드 랜더링)
- 개념
- 클라이언트(브라우저)에서 웹 페이지의 렌더링을 담당하는 방식
- 서버는 HTML 껍데기와 함께 필요한 JavaScript 파일을 클라이언트에 전달하고, 클라이언트에서 JavaScript가 실행되어 동적으로 페이지를 구성한다.
- 작동 방식
- 브라우저가 서버에 요청
- 서버는 기본적인 html과 js 파일을 반환
- 클라이언트에서 js가 실행되어 DOM을 구성하고 데이터를 받아와 화면을 동적으로 렌더링
- 특징
- 처음 로딩 속도가 느릴 수 있음 (js 실행 대기)
- 이후 페이지 간 이동은 빠름 (SPA 방식)
- 데이터를 동적으로 받아오기 때문에 인터랙티브한 UI 구현에 유리.
- API 호출을 통해 필요한 데이터만 받아와 클라이언트에서 렌더링.
- 장점
- 더 나은 ux 제공
- 서버 부하 감소, 네트워크 요청 최소화(필요한 데이터만 가져옴)
- 단점
- seo(검색 엔진 최적화)에 불리함
- 초기 로딩 속도가 느릴 수 있음
SSR 서버사이드 랜더링 → html의 조립이 다 끝난 상태로 넘어감
- 개념
- 서버에서 HTML을 완성하여 브라우저에 전달하는 방식. 브라우저는 전달받은 HTML을 바로 화면에 렌더링. 모든 페이지 요청마다 서버에서 새로운 HTML이 생성.
- 작동방식
- 브라우저가 서버에 요청을 보냄.
- 서버에서 HTML을 조립하고 완성된 페이지를 반환.
- 브라우저는 받은 HTML을 바로 렌더링.
- 특징
- 첫 로딩 속도가 빠름 (완전한 HTML 제공).
- 페이지 이동 시마다 서버에 새 요청을 보냄
- SEO(검색 엔진 최적화)에 유리 (HTML이 이미 준비된 상태
- 장점
- 초기 렌더링 속도가 빠름
- SEO에 최적화된 구조.
- 단점
- 서버 부하가 증가할 수 있음.
- 페이지 간 이동 시 전체 새로고침이 발생
- 동적인 UI 구현이 번거로울 수 있음.
'Spring' 카테고리의 다른 글
| [오르미 백엔드7기](Spring 프록시객체, 지연로딩 ,즉시로딩, 영속성전이, N+1문제) (1) | 2024.11.25 |
|---|---|
| [오르미 백엔드 7기] (Spring Entity 개념, 연관관계, 공통속성정의) (0) | 2024.11.25 |
| [오르미 백엔드7기] (Spring JPA 기본,ORM이란? , JDBC) (0) | 2024.11.22 |
| [오르미 백엔드 7기] (Spring Controller, thymeleaf 실습) (1) | 2024.11.19 |
| [오르미 백엔드7기] (Spring DI, IOC, AOP, Annotation) (0) | 2024.11.14 |