$(document).click(function(e){ //문서 body를 클릭했을때

    //User 영역 컨트롤

    if(e.target.className =="btn-user"){ //유저정보 클릭 버튼

        $(".user").toggle();

    }else if( $(".user").has(e.target).length > 0 ){ //유저정보 영역

        return false;

    }else { //그외 지역

        $(".user").css("display","none");

    }

});

btn-user 은 클릭했을떄 영역을 여는거고, use 는 그 영역이다.

'Web개발 > Javascript' 카테고리의 다른 글

이모티콘 오라클,Mysql 저장에러 정규식 체크  (1) 2019.06.06

<button> 태그에 type="button" 이 없고 부모 element 에 <form> 태그가 있을경우.

IE11에서 테스트 결과 <button> 을 submit 해버림. IE 에서는 default 를 submit 으로 자동지정하나 봄

@Entity 를 넣으면 @Id 가 필수로 들어가야 된다. (pk 를 인식하기위해)

 

@Id 로 들어가있는값이 save(id) 가 될경우 id값이 기존에 들어가있으면 update( merge() ) 가 처리가 되고 기존에 없는값이면 insert( persist() ) 처리가 된다.

 

즉 PK가 없이 계속 insert 를 하려고 했을경우, 다른방법을 사용해야 한다.

 

전 native 쿼리를 사용해서 insert 문을 적었습니다.

 

 

request 에서 URL 정보를 가져왔을때, url 에 있는값이 PathVariable 인지 알수가 없음.

 

그래서 URL 에서 pathVariable 변수명으로 치환하기 위한 로직. (이 URL 을 가져와서 URL 별 권한이 있는지 DB에서 조회하기 위해서 사용함)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    
/*
*  3. PathVariable 정보 Map 으로 가져오기
*/
Map<StringString> pathVariables = (Map<StringString>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
 
// URL 에서 PathVariable 부분을 replace
Iterator<String> itr = pathVariables.keySet().iterator();
String key = null;
String value = null;
String[] splitStr = url.split("/");
while (itr.hasNext()) {
    key = (Stringitr.next();
    value = pathVariables.get(key);
    for (int i = 0; i < splitStr.length; i++) {
        if (splitStr[i].equals(value)) {
            splitStr[i] = "{" + key + "}";            
            }
    }
    url = String.join("/"Arrays.asList(splitStr));

 

'Web개발 > Java' 카테고리의 다른 글

날짜 유효성 체크 어노테이션  (0) 2019.12.04
@SpringBootTest 와 @WebMvcTest 차이  (0) 2019.07.07

PUT, DELETE 메소드로는 Web 서비스와 함께 원격지 웹 서버에 파일을 생성하거나 삭제하는 FTP와 유사한 기능을 구현할 수 있다.

 

그러면 get 이랑 post 만 써서 rest api 를 만들어야 되나???

Nope !

 

Url 파라미터로 _method=PUT , _method=DELETE 를 사용하고

웹서버 Filter 에서 _method 파라미터의 value값을 http method로 변경하는 spring filter 가 "HiddenHttpMethodFilterConfiguration" 이다.

 

사용은 간단하다. 아래클래스 하나 만들면 끝.

 

그러면 GET,POST 메소드만 Request 를 받도록 제한을 하려면??????

 

CorsWebFilter 를 사용하면 된다.

========================================================================

 

1
2
3
4
5
6
7
8
@Configuration 
public class HiddenHttpMethodFilterConfiguration { 
 
@Bean 
public HiddenHttpMethodFilter hiddenHttpMethodFilter() { 
    return new HiddenHttpMethodFilter(); 
   } 
}

버튼 한개당 API 를 여러개 호출할경우

 

버튼은 권한 있지만 API 는 권한관리 를 어떻게 할것인가.

 

테이블관계가 메뉴:버튼(1:N) 으로 API 별로 권한을 체크하려니 테이블 관계 버튼:API 가 (N:N) 관계가 되면서 권한 체크가 쉽지 않게 되었다. (버튼 한개에 API 한개를 호출하면 좋겠지만 MSA 프로젝트를 한다면 그럴거 같지는 않음)

 

1. '메뉴기능 테이블'에 버튼권한을 다 넣고, 거기에 모든 API 를 관리하는 테이블에 넣은후 권한을 체크.

 // API 추가시 계속 URL 을 관리해야하는 번거로움. (conference에 추가하는거나 비슷한거 같기도하고...)

 

2. URL 패턴을 관리해서 특정URL 패턴에서만 URL 권한을 체크하도록

ex) Intercepter 에서 !URL.startsWith("/uploads") 이럴때 권한 체크. 등으로 처리

 // 2번과 같이 처리하려면 시작부터 url 패턴을 정해두어야함.

API Server 앞에 NginX 를 프록시서버로 뒀을때 , API Server 에서 아무리 Header 정보 아무리 찾아봐도,

Client 정보를 알수가 없다. Nginx 가 헤더정보를 안 넘겨주기 때문이다.

 

이럴경우 Nginx 헤더 설정이 필요하다.

 

위에 언급한 Nginx 같은걸 Ingress(라우터 외부에서 라우터 내부로 유입되는 패킷을 필터링) 서버 라 부른다.

API Server 앞에 NginX 를 프록시서버로 뒀을때 , API Server 에서 아무리 Header 정보 아무리 찾아봐도,

Client 정보를 알수가 없다. Nginx 가 헤더정보를 안 넘겨주기 때문이다.

이럴경우 Nginx 헤더 설정이 필요하다.
위에 언급한 Nginx 같이 클러스터 외부에서 내부로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙들의 모음을
 쿠버네티스에서는 Ingress 서버 라 부른다.
 
 Ingress로 Nginx 를 사용할경우 yaml 템플렛 annotations 부분에 아래와 같이 추가하면 클라이언트 정보를 알 수 있다.

 
metadata:
   annotations:
      proxy_set_header X-Forwarded-For $proxy_protocol_addr;
      proxy_set_header X-Real-IP $proxy_protocol_addr;

참고 : https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/

1. 커스텀 어노테이션 생성.

2. validate 부분 작성.

3. VO에 적용.

 

1.  커스텀 어노테이션 생성.

@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FromDateBeforeOrSameAsToDateValidator.class)
@Documented
public @interface FromDateBeforeOrSameAsToDate {
    String message() default "시작일은 종료일보다 클수 없습니다";

    Class[] groups() default {};

    Class[] payload() default {};

    String searchFromDt();

    String searchEndDt();

    @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List
    {
        FromDateBeforeOrSameAsToDate[] value();
    }
}

 

2. validate 작성.

public class FromDateBeforeOrSameAsToDateValidator implements ConstraintValidator<FromDateBeforeOrSameAsToDate, Object> {

    private String searchFromDt;
    private String searchEndDt;

    @Override
    public void initialize(FromDateBeforeOrSameAsToDate constraintAnnotation) {
        searchFromDt = constraintAnnotation.searchFromDt();
        searchEndDt = constraintAnnotation.searchEndDt();
    }

    @Override
    public boolean isValid(Object requestObject, ConstraintValidatorContext constraintValidatorContext) {
        Field fromDateField = FieldUtils.getField(requestObject.getClass(), searchFromDt, true);
        Field toDateField = FieldUtils.getField(requestObject.getClass(), searchEndDt, true);

        String fromLocalDate = (String) ReflectionUtils.getField(fromDateField, requestObject);
        String toLocalDate = (String) ReflectionUtils.getField(toDateField, requestObject);

        SimpleDateFormat transFormat = new SimpleDateFormat("yyyyMMdd");
        transFormat.setLenient(false); //유효한 날짜인지 체크 예를들어 2019/01/32 이런거 체크
        Date from = new Date();
        Date to = new Date();

        if (fromLocalDate == null || toLocalDate == null) {
            return true;
        }

        try {
             from = transFormat.parse(fromLocalDate);
             to = transFormat.parse(toLocalDate);
            if(from.compareTo(to) > 0){ // Date 1 occurs after Date 2
                return false;
            }
        } catch (ParseException e) {
            constraintValidatorContext.buildConstraintViolationWithTemplate("유효하지 않은 날짜 입니다.") .addConstraintViolation();
            return false;
        }

        constraintValidatorContext.disableDefaultConstraintViolation();
        constraintValidatorContext.buildConstraintViolationWithTemplate(
                "시작일은 종료일보다 클수 없습니다.")
                .addConstraintViolation();

        return fromLocalDate.equals(toLocalDate) ||  (from.compareTo(to) < 0);
    }
}

 

3. VO에 적용.

@FromDateBeforeOrSameAsToDate.List({ @FromDateBeforeOrSameAsToDate(searchFromDt = "regStartDate", searchEndDt = "regEndDate" })
public class EmployeeContractDelivery extends BaseObject {

        /*등록시작일자*/
        private String regStartDate;
        /*등록종료일자*/
        private String regEndDate;

 

        public String getRegStartDate() {
            return regStartDate;
        }  
        public void setRegStartDate(String regStartDate) {
            this.regStartDate = regStartDate;
        }
        public String getRegEndDate() {
            return regEndDate;
        }
        public void setRegEndDate(String regEndDate) {
            this.regEndDate = regEndDate;
        }

}

'Web개발 > Java' 카테고리의 다른 글

Url PathVariable 변수명 가져오기  (0) 2020.03.05
@SpringBootTest 와 @WebMvcTest 차이  (0) 2019.07.07

+ Recent posts