728x90

삼각형의 조건: 가장 긴 변의 길이가 나머지 변의 합 보다 작아야 한다.       

두 변의길이가 주어질 때 가능한 나머지 변의 길이의 개수는?   

 

public int solution(int[] sides) {

int answer = 0;

//1.최대 sides[0]+sides[1]보다 작아야한다.

//2.sides중 최댓값이 나머지 값과 더할 값의 합보다 작아야 한다.

int max = Math.max(sides[0], sides[1]);

int min = Math.min(sides[0], sides[1]);

int sum = sides[0]+sides[1];

//answer>max-min;

//max-min=Math.abs(sides[0]-sides[1]);

//answer>Math.abs(sides[0]-sides[1]);

//answer<sides[0]+sides[1];

answer = sides[0]+sides[1]-Math.abs(sides[0]-sides[1])-1;

return answer;

}

'Java > Coding Test' 카테고리의 다른 글

한번만 등장한 문자 문제풀이  (0) 2023.09.17
등수 매기기 문제풀이  (0) 2023.09.15
영어가 싫어요 문제풀이  (0) 2023.09.14
공 던지기 문제풀이  (0) 2023.09.14
숨어있는 숫자 덧셈(2) 문제풀이  (0) 2023.09.13
728x90

addViewControllers는 컨트롤러를 직접 구현하지 않고 URL 매핑을 설정하는 데 사용된다.

이 메서드는 특정 URL로 요청이 들어올 때 컨트롤러 클래스를 작성하지 않고도 뷰로 직접 매핑하고 싶을 때 유용

 

addViewControllers를 사용하면 간단한 URL 매핑 및 뷰 템플릿과의 연결을 설정할 수 있어서 프로젝트의 구조를 간소화하고 유지보수를 편리하게 할 수 있다. 

 

@Configuration

public class WebConfig implements WebMvcConfigurer{

@Override

public void addViewControllers(ViewControllerRegistry registry) {

registry.addViewController("/").setViewName("forward:/index.jsp");

}

}

/ URL에 대한 뷰 컨트롤러를 구현하는대신 

/ URL로 들어오는 요청을 "forward:/index.jsp"로 매핑하였다. 

 

'Java > Spring Boot' 카테고리의 다른 글

Spring Data JPA begins  (0) 2023.10.06
Spring CRUD with RestAPI  (0) 2023.09.20
Thymeleaf in Spring  (0) 2023.09.14
Spring Interceptor  (0) 2023.09.14
JSTL coreTag  (0) 2023.09.13
728x90

thymeleaf 템플릿 엔진은 서버에서 클라이언트측으로 데이터를 전달하고 html에 표시할 수 있는 서버측 Expression Language를 제공한다. 

 

html에서 thymeleaf를 사용할때 

<html xmlns:th="http://www.thymeleaf.org">

html에 xml namespace "http://www.thymeleaf.org로 설정

 

thymeleaf의 prefix는 th이다.

 

expressions

- ${...} : variable expressions                     //변수

- *{...} : selection expressions                    //선택된 변수의 하위 프로퍼티

- #{...} : message(i18n) expressions          //국제화

- @{...} : link(url) expressions                     //link 

- ~{...} : fragment expressions                    //코드조각 

 

<div th:fragment="left" th:remove="tag">

<p>

<strong>메 뉴</strong>

</p>

<ul>

<li><a href="guest_main">방명록홈</a></li>

<li><a href="guest_list">방명록리스트</a></li>

<li><a href="guest_write_form">방명록쓰기폼</a></li>

</ul>

</div>

- th:fragment="name"

코드 조각에 이름을 설정해주면 코드조각을 사용할 수 있다. 

 

- th:remove="tag"

 다른 템플릿에서 코드조각을 사용할 때 제거하고 싶은 부분이 있을 때 사용한다. 

위 코드에선 "left" fragment 를 다른 곳에 삽입 했을 때 <div>태그 내의 내용은 삽입되지만 <div>태그는 remove된다.

 

navigation bar, header, footer 같이 많은 페이지에서 사용하는 템플릿은 fragment로 지정하여 하나의 템플릿으로 모아서 사용할 수 있다. 

 

<div id="header" th:insert="~{include_common :: top}">

공통으로 들어가는 top header부분에 name="top"인 fragment를 삽입

th:insert="~{include_common::top}"

 

~{html :: fragmentName} : fragment expression

include_common.html 파일의 top fragment 

<div id="header" th:insert="include_common :: top">

~{} expression을 생략해도 적용이 되긴한다. 

 

<tr th:each="guest:${guestList}">

<a href="guest_view?guest_no=223" th:href="@{guest_view(guest_no=${guest.guest_no})}" class="user" th:text="${guest.guest_title}">타이틀</a>

<td width=120 align=center bgcolor="ffffff" th:text="${guest.guest_date.substring(2,10)}">2023-09-11</td>

</tr>

${variable} : variable expressions

th:each  반복문

 

th:each="사용할 단위객체 변수명(guest):객체배열(${guestList})"

이후 속성 scope 내에서  guest를 사용할 수 있다. 

 

th:href="@{link url}"

 

th:text 

text를 덮어씌운다. 

 

<form name="f" method="post" th:object="${guest}">

<input type="hidden" th:field="*{guest_no}"/>

<table>

<tr>

<td>번호</td>

<td th:text="*{guest_no}">159</td>

</tr>

th:object="객체"

th:object를 지정해주면 해당 태그 내에서 *selection expression 사용할 수 있다. 

기존에는 ${object.field} 로 접근하였다면 object를 지정해주면 *{field}로 object를 생략하고 field를 쓸 수 있다. 

 

th:field="데이터 바인딩 하려는 모델객체의 필드네임"

th:field 속성은 name과 id를 자동으로 생성해주고 value값을 바인딩해준다. 

<input type="hidden" th:field="*{guest_no}"/>

<input type="hidden" name="guest_no" id="guest_no" value="*{guest_no}" th:value="*{guest_no}"/>

위 th:field 속성을 사용하면 아래와 유사하다고 생각하면 된다.

 

 

<div th:fragment="left" th:remove="tag" >

<p>

<strong th:text="#{menu.title}">메뉴</strong>

</p>

 

<th:block th:if="${session.sUserId!=null}">

<ul>

<li><a href='user_view' th:text="${#messages.msg('menu.id',session.sUserId)}"> 땡땡</a></li>

<li><a href='user_view' th:text="#{menu.myinfo}">내정보</a></li>

<li><a href="user_logout_action" th:text="#{menu.logout}">로그아웃</a></li>

</ul>

</th:block>

 

<th:block th:unless="${session.sUserId!=null}">

<ul>

<li><a href="user_login_form" th:text="#{menu.login}">로그인</a></li>

<li><a href="user_write_form" th:text="#{menu.join}">회원가입</a></li>

</ul>

</th:block>

</div>

위 navigation bar "left" fragment의 업그레이드버전이다. 

로그인 상태와 로그인 하지 않은 상태에 따라 메뉴를 다르게 표시하게 하였다. 

<th:block th:if="${session.sUserId!=null}">

th의 태그인 <th:block>을 사용하여 다르게 설정할 부분을 묶고 th:if 속성을 사용하였다. 

model의 데이터는 바로 가져올 수 있었지만

session의 데이터는 session을 거쳐야 했다.

"${session.sUserId}"

 

th:if="boolean값"

th:unless="boolean값"

<th:block th:if="${session.sUserId!=null}">

<th:block th:unless="${session.sUserId!=null}">

th:if => true이면 실행

th:unless => false이면 실행

 

th:text="#{menu.myinfo}"

messages 설정파일의 key값 menu.myinfo의 value를 #{message expression}으로 가져온다. 

 

menu.id={0} 님

user.properties에 설정한 다국어 message map이다. 

{0} 으로 인자를 한개 받는다.

기존 #{message} 에 인자를 받는 부분이 추가로 필요하다.

 

<th:text="#{menu.id(${session.sUserId})}">떙떙님

<th:text="${#messages.msg('menu.id', session.sUserId)}">떙떙님

parameter를 변수로 받을 때 표현식이다. 

 

1.#{messageKey(${param})}

기존 #{messageKey}에 (변수) 를 추가한다.

 

2.${#messages.msg('messageKey',param)}

메세지를 처리하기 위한 유틸리티 객체 #messages.msg() 함수를 이용해 값을 받는다.

 

 

 

 

https://www.thymeleaf.org/documentation.html

 

Documentation - Thymeleaf

Articles Quick glimpses into what Thymeleaf can bring to your project. Introductions With Spring Comparisons

www.thymeleaf.org

 

 

타임리프 document 

'Java > Spring Boot' 카테고리의 다른 글

Spring CRUD with RestAPI  (0) 2023.09.20
Spring addViewControllers  (0) 2023.09.14
Spring Interceptor  (0) 2023.09.14
JSTL coreTag  (0) 2023.09.13
Spring CustomTag SPEL(Spring Expression Language)  (0) 2023.09.13
728x90

웹 사이트를 만들다보면 여러페이지에서 동일한 설정, 또는 검사를 반복해야하는 경우가 있다. 

그럴경우, 필터나 인터셉터로 처리할 수 있다. 

 

 

 

Filter는 요청과 응답을 정제하는 역할을 한다. 

web.xml 또는 application.properties에서 설정하고 보통 인코딩 처리를 한다. 

Filter는 DispatcherServlet 이전, DispatcherServlet이 응답을 반환 후에 실행하기 때문에 

Filter를 통해 자원의 처리 이전 요청 내용을 변경하거나 자원을 처리한 후 응답을 변경할 수 있다. 

 

init(): 필터 인스턴스 초기화

doFilter(): 필터 전/후 처리

destroy(): 필터 인스턴스 종료

 

web.xml 에서 UTF-8 인코딩

<filter>

<filter-name>encoding</filter-name>

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>encoding</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

url-pattern을 /*로 설정하면 servlet, jsp, img 등 모든 자원에 적용된다.

 

application.properties에서 인코딩 필터 설정하기

 

 

하지만 자원의 처리과정 중 필요한 처리는 수행하지 못한다. 

그럴때 Interceptor를 사용한다. 

 

Interceptor는 DispatcherServlet이 HandlerMapping 직후 Controller을 호출하기 직전, 직후, View를 Rendering한 후 실행된다. 

Interceptor는 여러개 사용할 수 있고, Controller에서 요청을 처리하기 전 로그인 체크, 권한 체크, 처리 한 후 실행 시간 계산과 같은 작업을 수행할 수 있다. 

 

preHandle(): Controller 요청 처리 전

postHandle(): Controller 요청 처리 후

afterCompletion(): View Rendering 후

 

Interceptor 만들기 

 

-HandlerInterceptor 인터페이스를 상속받아 메소드를 구현한다. 

 

public class AuthLoginInterceptor implements HandlerInterceptor {

public AuthLoginInterceptor() {

}

 

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

 

/***********************************************************************************

1. handler객체 종류 확인

우리가 관심 있는 것은 @Controller객체에 있는 매핑된(@RequestMapping이 붙은) 메서드이므로

HandlerMethod 타입인지 체크

*************************************************************************************/

if (handler instanceof HandlerMethod == false) {

/*

* @ Controller객체에 @RequestMapping이 붙은메쏘드 : HandlerMethod

*/

//return true이면 그대로 컨트롤러로 진행

return true;

}

 

HttpSession session = request.getSession();

String sUserId = (String) session.getAttribute("sUserId");

if (sUserId == null) {

response.sendRedirect("user_main");

return false

}

return true;

}

}

로그인 상태 확인을 위한 Interceptor로 Controller 호출 전 Interceptor에서 로그인 상태를 확인하고

로그인이 되어 있을 때만 Controller를 호출할 수 있게 한다. 

 

반환 값은 boolean 타입으로 true면 Mapping된 Controller를 호출하고 false면 Controller로 가지 않고 실행을 멈춘다. 

위 코드에서는 로그인이 되어있지 않은 상태면 main페이지로 redirect 했는데 

Interceptor는 Controller가 아니기 때문에 redirectPath를 반환하거나 main Controller uri로 보낼 수 없고 

파라메터로 받은 response로 직접 redirect한다. response.sendRedirect();

 

 

 

preHandle메소드를 보면 Object handler 객체를 받는다. 

handler객체는 @requestMapping이 된 메소드의 정보(컨트롤러, 메타정보, 파라메터, 어노테이션 메타정보, 리턴 값 메타정보..)를 가지고 있는 HandlerMethod객체이다.

 

if (handler instanceof HandlerMethod == false) {

// @ Controller객체에 @RequestMapping이 붙은메쏘드 : HandlerMethod

//return true이면 그대로 컨트롤러로 진행

return true;

}

handler가 mapping된 handlerMethod인지 확인하는 작업으로 

맵핑이 안된 메소드면 바로 Controller로 이동 

 

이후 필요한 작업(로그인 확인 처리)를 하면 된다. 

 

Annotation을 이용한 Interceptor를 만들 때는 

 

HandlerMethod를 확인하고 HandlerMethod객체의 어노테이션 메타 정보를 가져와 확인하는 작업을 추가한 후 필요한 작업을 하면 된다.

//2.HandlerMethod 타입으로 형 변환

HandlerMethod handlerMethod = (HandlerMethod) handler;

 

//3.HandlerMethod객체 로부터 @LoginCheck 어노테이션 객체얻기

 

LoginCheck loginCheck = handlerMethod.getMethodAnnotation(LoginCheck.class);

 

//4. HandlerMethod객체에 @LoginCheck어노테이션 이없는 경우,

즉 인증이 필요 없는 요청

if (loginCheck == null) return true;

//4. HandlerMethod객체에 @LoginCheck어노테이션 이있는 경우, 로그인 체크...

 

Interceptor를 구현한 후 

WebConfig나 mvc-config.xml 에 Interceptor를 등록한다.

 

Annotation을 사용하지 않는 경우 

@Override

public void addInterceptors(InterceptorRegistry registry) {

 

AuthLoginInterceptor authLoginInterceptor=new AuthLoginInterceptor();

registry.addInterceptor(authLoginInterceptor)

.addPathPatterns("/**")

.excludePathPatterns("/css/**")

.excludePathPatterns("/js/**")

.excludePathPatterns("/image/**")

.excludePathPatterns("/user_main")

}

addInterceptors 메소드에서 registry에 Interceptor를 추가하고 pathPattern을 추가하거나 제외한다.

 

@Override

public void addInterceptors(InterceptorRegistry registry) {

 

AuthLoginAnnotationInterceptor authLoginAnnotationInterceptor=

new AuthLoginAnnotationInterceptor();

registry.addInterceptor(authLoginAnnotationInterceptor)

.addPathPatterns("/**")

.excludePathPatterns("/css/**")

.excludePathPatterns("/js/**")

.excludePathPatterns("/image/**");

 

}

 

Annotation을 사용하는 경우

Interceptor를 Annotation을 적용한 Interceptor를 추가한다. 

 

mvc-config.xml파일에서 설정할 경우

<mvc:interceptors>

    <mvc:interceptor>

         <mvc:mapping path="/**"/>

         <bean class="com.itwill.user.controller.AuthLoginAnnotationInterceptor" />

     </mvc:interceptor>

</mvc:interceptors>

 

'Java > Spring Boot' 카테고리의 다른 글

Spring addViewControllers  (0) 2023.09.14
Thymeleaf in Spring  (0) 2023.09.14
JSTL coreTag  (0) 2023.09.13
Spring CustomTag SPEL(Spring Expression Language)  (0) 2023.09.13
Spring Boot Controller Type of Parameters  (0) 2023.09.13

+ Recent posts