과제하며 다시 공부

stella·2021년 9월 6일
0

1. Template

jdbcTemplate.queryForObject(
"select * from voucher WHERE voucher_id=UUID_TO_BIN(?)",
customerRowMapper, 
voucherId.toString().getBytes()));

queryForObject(쿼리, 반환값, 인자에 넣어줄 값)
query(쿼리, 반환값): list 형태로 반환 결과를 얻을때

2. UUID

  static UUID toUUID(byte[] bytes){
        var byteBuffer= ByteBuffer.wrap(bytes);
        return new UUID(byteBuffer.getLong(),byteBuffer.getLong());

    }

3. Test

@ExtendWith(SpringExtension.class):TestApplicationContext만들어줌,junit에서 실제 스프링테스트 프레임워크를 사용할 수 있도록 해준다
@ContextConfiguration : AppConfiguration을 읽어서 ApplicationContext만들어준다.

  • (classes = {AppConfiguration.class})-> 프로파일이나 다른 설정때문에 오류가 날 수 있기 때문에 Test용 configuration을 만들어 주기도함

@SpringJUnitConfig:@ExtendWith@ContextConfiguration 합쳐 동작

@Beforall ->static 관련 다시 공부하기!

4. Tymeleaf 문법

  • 클릭 이벤트에 변수있는 url 넘겨줄때
<tr th:each="voucher: ${vouchers}" th:object="${voucher}" th:onclick="'location.href=\''+ @{/voucher/{id}(id=${voucher.voucherId})} + '\''"  >
  • 라디오 버튼으로 값가져오기(name=(dto의) 필드명,value= 필드에 들어간 값)
 <div class="mb-3">
        <div>Type 선택 (한 개만 선택 가능)</div>
        <div>
            <label> Fixed<input type="radio" name="type" value="Fixed"></label>
            <label> Percent<input type="radio" name="type" value="Percent"></label>
        </div>

    </div>

5. MessageConverter

  • 이전에는 Model object에 넣어 view를 리턴하는 방식이었지만
    MessageConverterHTTP요청 메세지 본문과 HTTP응답 메세지 본문을 각각 하나의 메세지로 보고 처리 한다. 이때 사용하는 어노테이션이@RequestBody @ResponseBody이다

@RequestBody : HTTP 요청을 해석하는 것이 아니라 하나로 받아서 객체로 변환
@ResponseBody: HTTP 응답메세지에 리턴한 값의 객체를 전달 할 수 있다.

  • Default Message converters
    HttpMessageConverter에 미리 등록되어 있는 것들이다 @EnableWebMvc으로 등록 해줄수 있다.
    (많은 컨버터들이 이미 알아서 동작해서 string값으로 받아올 수 있는거고 그렇다..)
    참고 이거 보고 정리해야함
        @Override
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {


            var messageConverter = new MarshallingHttpMessageConverter();
            var xStreamMarshaller = new XStreamMarshaller();
            //xml로 바꿔준다.
            messageConverter.setMarshaller(xStreamMarshaller);
            //xml을 자바 객체로 바꾸어 준다.
            messageConverter.setUnmarshaller(xStreamMarshaller);
            //맨앞에서 실행하도록 한다. json accept 가능
            converters.add(0,messageConverter);

            //시간 원하는 형태로 출력하기 위해서 확장
             var javaTimeModule = new JavaTimeModule();
             javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME));
            var modules = Jackson2ObjectMapperBuilder.json().modules(javaTimeModule);
            //확장한 모듈을 converter에 넣어준다.
            converters.add(1,new MappingJackson2HttpMessageConverter(modules.build()));

        }

6. Restful API

Controller vs RestController

@Controller: 뷰를 반환하기 위해 사용됨
@Response Body:컨트롤러에서 json 같은 데이터를 반환 해야할 때

@RestController: @RestController:@Controller+@Response Body

@RestController은 viewResolver 대신에 HttpMessageConverter가 동작한다. HttpMessageConverter가 알아서 json형식으로 바꾸어 주기 때문에 별도의 @Response Body를 붙이지 않아도 json등으로 전송할 수 있다. (viewResolver 때문에 그냥 controller에서 @Response Body@Request Body를 붙이지 않는다면 view이름으로 찾게 된다.)

ResponseEntity<> :http 리스펀스에 대한 헤더나 상태코드를 처리 하기 위해서 쓰인다.

 @GetMapping("/api/v1/customers/{customerId}")
    @ResponseBody
   
    public ResponseEntity<Customer> findCustomer(@PathVariable("customerId") UUID customerId){

        var customer=customerService.getCustomer(customerId);
        
        return customer.map(v->ResponseEntity.ok(v))
                .orElse(ResponseEntity.notFound().build());

    }

ok(v)-> 만약에 있다면 리턴
.orelse()-> 상태코드 정의
--> 반환값이 Optional이라면 처리를 간편하게 할 수 있다.

id와 type으로 조회할때 url mapping이 같은 경로에 있으면 안된다

@GetMapping("/api/v1/voucher/{Id}")
@GetMapping("/api/v1/voucher/{type}")

IllegalStateException:Ambiguous handler methods mapped for URL 오류발생!!!!

출처: https://koeiking11.tistory.com/entry/Spring-Boot-Ambiguous-handler-methods-mapped-for [코더에서 개발자로 가는길.]

DeleteMapping 오류 (thymeleaf)

삭제(DeleteMapping)는 method post으로 설정해 주어야 한다. form으로 받아와줬다.

<td th:class="btn">
  <form id="deleteMember" th:action="@{/voucher/delete/{id}(id=${voucher.voucherId})}" method="post">
     <input type="hidden" name="_method" value="delete"/>
     <button id="delete-btn" class="btn">delete</button>
  </form>
</td>
profile
뚠뚠뚠..

0개의 댓글