반응형

software.amazon.awssdk.services.sns.model.InvalidParameterException: Invalid parameter: TopicArn

 

원인 : 프로젝트에 topic region설정을 잘못함

내 토픽 region은 ap-northeast-1인데

프로젝트 설정은 2로 해놓음 ㅎㅎ;;

 

반응형
반응형

SNS와 SQS 정리
SNS : Publisher가 Subscriber에게 메시지를 전송하는 서비스
SQS : 메세지 대기열 서비스

SNS 역할
특정 서비스에서 SNS로 지정한 주제(topic)에 대한 메시지를 발행한다. 예)회원가입정보
그럼 이 SNS는 이 topic에 대한 메시지를 받아보기로 한 (subscribe한) 서비스들에게 메시지를 전달해준다.
subscribe를 하는 주체는 SQS, Lambda, HTTP, SMS, 이메일, 모바일 애플리케이션 엔드포인트가 될 수 있다.

SQS 역할
SQS는 Simple Queue Service로, 메세지 대기열 서비스라고 함.
SNS로부터 특정 주제의 메세지를 구독하여 받아볼 수 있다.
그럼 특정 서비스나 시스템에서 SQS로 받은 메시지를 사용하면 되는거임

흐름은 이렇게 됨
서비스 -> SNS -> SQS -> 다른 서비스

즉 SNS와 SQS를 활용하면 엔드포인트에서 엔드포인트로 데이터를 직접 때려박지 않아도 되므로 데이터 안전성과 관리 오버헤드 제거에 있어서 용이하겠다. . . 

1. SNS 주제 생성하기


https://ap-northeast-1.console.aws.amazon.com/sns/v3/

주제 이름 적고 다음단계로 ㄱㄱ

표준으로 ㄱㄱ 하고 다른 옵션들은 모두 주어진대로 ㄱㄱ

생성되었다.

 


2. SQS 대기열 생성하기


https://ap-northeast-1.console.aws.amazon.com/sqs/v2/

 

대기열 생성 ㄱㄱ

표준으로 하고 다른 옵션들은 기본으로 ㄱㄱ

생성되었다.

 

 


3. SNS 구독하기

생성한 대기열(MyQueue)이 만들었던 SNS의 주제를 바라보도록 설정해야한다. (publish)

'Amazon SNS 주체 구독' 선택

내가 만들었던 Topic을 선택해줌.

SQS에서 설정된것 확인

SNS에서도 설정된것 확인

 


4. SNS 메시지발행

구독 설정이 잘 되었나 확인해볼것.

SNS에서 메시지 게시

제목과 메시지 본문을 적고 기본 옵션으로 전송

 

5. 메시지 수신

MyQueue에서 메시지를 받아보자

메시지 폴링을 누릅니다.

 

SNS 에서 발행한 메시지가 보입니다.

메시지 아이디를 눌러보면 아래와 같은 메시지가 표시됨.  성공~ 

{
  "Type" : "Notification",
  "MessageId" : "d118fffff-dddd-cccc-bbbbb-aaaaaaaa",
  "TopicArn" : ":MyTopic",
  "Subject" : "TEST~~TITLE~~",
  "Message" : "TEST~~PAYLOAD~~~",
  "Timestamp" : "2023-02-02T00:11:52.300Z",
  "SignatureVersion" : "1",
  "Signature" : "==",
  "SigningCertURL" : "",
  "UnsubscribeURL" : ""
}

 

다음은 SNS 와 SQS 를 Spring Boot에 연동해서 메세지 보내고 받아보기~

https://mchch.tistory.com/281

 

SpringBoot에서 SNS SQS 연동하기

SpringBoot에서 SNS로 메세지 발행하기 SQS로 받은 메시지 Springboot에서 받아보기 개발환경 : Intellij, java17, gradle 1. 의존성 설정 implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.sp

mchch.tistory.com

 

반응형
반응형

the request was rejected because no multipart boundary was found 에러가 났다.

 

 

Content-Type 지정한걸 빼버리면 된다 

Content-Type: multipart/form-data
반응형
반응형

Windows 에서 설치 및 테스트 하였음

 

1. H2 다운로드

https://www.h2database.com/html/main.html

windows Installer 다운로드하여 설치하였음.

 

 

2. 설치 확인

C:\Program Files (x86)\H2\bin 경로에서 설치파일들 확인하고 bin밑의 h2.bat을 클릭

 

cmd 창이 켜지며 실행됨. 인터넷 브라우저로 콘솔창이 켜짐.

cmd창을 끄면 db실행이 중단되는 것 같다.

 

 

3. 접속하기

브라우저 콘솔창에서 접속해서 H2 Server 이나 H2 Embedded 중 선택하면 됨. 

>> Embedded 모드
시스템의 메인 메모리에서 구동시키는 방식
application이 종료된다면 저장, 수정된 Data가 사라짐.

>> Server모드
하나의 시스템에서 별도의 프로세스(JVM)를 통해 DB를 동작시켜 데이터베이스를 영속적으로 사용하는 방법

이때 연결을  누르면 데이터베이스 파일이 없어서 에러가 뜨는데, 에러에 표시된 경로에 들어가서 내용 없는 파일을 하나 만든다.

새로만들기 > 텍스트파일 (내용은 적지 않고 저장) > 파일 이름은 파일이름.mv.db 

생성 후 다시 연결을 해보면 연결이 된다. 

 

 

 

4. springboot와 연동하기 - 의존성 

h2와 jpa 의존성을 추가하였으며 전체 dependencies 내용은 아래와 같다.

dependencies {
    implementation 'com.h2database:h2'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

 

 

5. springboot와 연동하기 - 프로퍼티 설정

application.properties 파일에 아래 내용 추가 

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:tcp://localhost/~/springtest1
spring.datasource.username=sa

##JPA 실행시 sql문 출력
spring.jpa.show-sql=true

##테이블 생성여부.. create로 해두면 어플리케이션 실행 시 덮어쓰기로 테이블이 새로 생성됨. 
##데이터도 모두 지워진다는 거~~
##안 할 경우 none
spring.jpa.hibernate.ddl-auto=create

 

 

6. Entity 또는 domain 만들기 

테이블과 맵핑할 객체를 만들었다. (Member.java)

- @Entity 어노테이션 추가

- 키 컬럼에 @Id 추가

- 값의 자동생성과 자동증가를 위해 @GeneratedValue 추가

@Entity //객체와 테이블 매핑
public class Member {

    @Id //기본 키 매핑
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String name;

    private String address;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress(){
        return address;
    }

    public void setAddress(String address){
        this.address = address;
    }
}

 

 

7. Repository 만들기

DB에 접근하여 쿼리를 수행할 Repository를 인터페이스로 만들었다. (MemberRepository.java)

- @Repository 어노테이션  추가하고

- JpaRepository를 상속

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
    Member save(Member member);
    Optional<Member> findById(Long id);
    Optional<Member> findByName(String name);
    List<Member> findAll();
}

 

 

8. 테스트 해보기

테스트용 코드 작성~

@SpringBootTest
class Spring2ApplicationTests {

    private final MemberRepository memberRepository;

    // 의존성 주입
    @Autowired
    public Spring2ApplicationTests(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Test
    void memberTest() {
        // 멤버 저장
        Member member = new Member();
        member.setName("nameTestAAAAAA");
        member.setAddress("seoulAAAAAA");
        memberRepository.save(member);

        // 저장한 멤버 아이디로 검색
        Member findMember = memberRepository.findById(member.getId()).get();
        System.out.println(findMember.getAddress());
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());

    }
}

 

실행해보면 아래와같이 쿼리와 프린트 결과가 찍힌다~

 

DB 콘솔에서도 확인

반응형
반응형
Gradle could not start your build.  
> Could not create service of type ChecksumService using BuildSessionScopeServices.createChecksumService().

gradle daemon이 중복으로 실행되려 해서 그런 것 같다.

작업관리자에서 java 싹죽이고 IDE 다시 시작하니까 된다

반응형
반응형

java로 https 통신 연결하기 / java로 api 호출하기 / java post http 

//파라미터 담기
String strParam = "param1=apple&param2=banana&param3=grape";

// 요청 URL
reqUrl = "https://www.test.com/api1/api1_2";

//결과값 담을 변수
String returnStr 	   = "";

HttpsURLConnection con = null;

try {
 	URL url = new URL(reqUrl);
          
	StringBuffer buf = new StringBuffer();

	con = (HttpsURLConnection)url.openConnection();
    
	//http method 설정
	con.setRequestMethod("POST");
    
	//서버통신 timeout 설정 (30초)
	con.setConnectTimeout(30000);
    
	//스트림읽기 timeout 설정 (30초)
	con.setReadTimeout(30000);
    
	//헤더설정
	con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
	con.setRequestProperty("Authorization", "sdfsdfsdfsdf");

	//OutputStream으로 POST 데이터 전달 옵션
	con.setDoOutput(true);

	//연결
	con.connect();

	// 송신할 데이터 전송.
	DataOutputStream dos = new DataOutputStream(con.getOutputStream());
	dos.writeBytes(strParam);
	dos.flush();
	dos.close();
    
	//응답 읽기
	StringBuilder response = new StringBuilder();
	BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
	
	String line;
	while ((line = bufferedReader.readLine()) != null) {
		response.append(line);
	}
	bufferedReader.close();
	returnStr = response.toString();
    
} catch (Exception e) {
		e.printStackTrace();
} finally {
		//연결종료
		if (con != null) con.disconnect();
}
반응형
반응형

multiple select로 select 목록 만들기 / 다중 select 만들기 / 목록 넣고 빼기 

left select right select


소스

<table>
	<tr>
		<th>left select</th>
		<th></th>
		<th>right select</th>
	</tr>
<tr>
	<td>
		<select multiple="multiple" id='left_list'>
			<option value='1'>1</option>
			<option value='2'>2</option>
			<option value='3'>3</option>
		</select>
	</td>
	<td>
		<button href="#" onclick="moveToRight(); return false;" class="btn">==></button>
		<br><br>
		<button href="#" onclick="moveToLeft(); return false;" class="btn"><==</button>
	</td>
	<td>
		<select multiple="multiple" id='right_list'>
			<option value='a'>a</option>
			<option value='b'>b</option>
			<option value='c'>c</option>
		</select>
	</td>
</tr>
</table>


<script>
//오른쪽에서 제거하고 왼쪽으로 옮기기
function moveToLeft() {
	$('#right_list option:selected').each(function(index, obj) {
		var value = obj.value;
		var text = obj.text;

		$('#right_list').find('option[value="'+ value +'"]').remove();
		 
		
		$('#left_list').append('<option value="'+value +'">'+text+'</option>')
	});
}

//왼쪽에서 제거하고 오른쪽으로 옮기기
function moveToRight() {
	$('#left_list option:selected').each(function(index, obj) {
		var value = obj.value;
		var text = obj.text;
		
	
		$('#left_list').find('option[value="'+ value +'"]').remove();
		 

		$('#right_list').append('<option value="'+value +'">'+text+'</option>')
	});
}
</script>

 

**기타 select 관련 control

select의 value 가져오기

//vanilla javascript
document.getElementById('select_list').value

//jquery
$('#select_list').val()

 

select의 선택한 option DOM 가져오기

//vanilla javascript
document.getElementById('select_list').options[document.getElementById('select_list').selectedIndex]

//jquery
$('#select_list option:selected')

 

선택한 option DOM의 사용자 data property 접근

<option value="111" data-sub_type="num">옵션에 이런 property가 있는 경우</option>
//vanilla javascript(dataset으로 접근)
document.getElementById('select_quatro_list').options[document.getElementById('select_quatro_list').selectedIndex].dataset.sub_type

//jquery(data로 접근)
$('#select_quatro_list option:selected').data('sub_type')

 

select에 option 추가/제거

//option 붙이기
$('#select_list').append('<option value="엥">엥</option>')

//option 떼기
$('#select_list').find('option[value=vvv]').remove();

 

select 에서 선택된 options들 가져와서 반복문 돌리기

$('#select_list option:selected').each(function(index,obj){
	var value = obj.value;
	var cont_type = obj.dataset.cont_type;
	var text = obj.text
})

 

반응형
반응형

ROW_NUMBER() OVER PARTITION BY ORDER BY

PARTITION BY 기준으로 그룹핑한 뒤 ORDER BY로 순번 매기는 함수.

 

예를 들어 아래와 같은 테이블이 있다

@TEMP 테이블임.

@TEMP 테이블

 

[ REG_DATE 를 기준으로 그룹핑하여 ID 순으로 순번 매기기]

SELECT
	ID,
	REG_DATE, 
	ROW_NUMBER() OVER ( PARTITION BY REG_DATE ORDER BY ID ) 
FROM @TEMP

결과

11/1에는 김치와 콩차반을 샀군요

 

[ ID 를 기준으로 그룹핑하여 REG_DATE 순으로 순번 매기기]

SELECT
	ID,
	REG_DATE,
	ROW_NUMBER() OVER ( PARTITION BY ID ORDER BY REG_DATE ) 
FROM @TEMP

결과

김부각은 11월 2일과 11월 10일 두 번 샀군요

 

이렇게 쓰는 것이었다

반응형
반응형

input type이 number인경우 maxlength 속성이 안 먹습니다.

함수를 걸어줘야 합니다.

<input type="number" maxlength="4" oninput="maxLengthCheck(this)"/>

해당 dom의 maxlength속성을 사용하므로 maxlength 속성은 지우면 안 댐.

<script type="text/javascript">
	
function maxLengthCheck(object){
  if (object.value.length > object.maxLength){
   object.value = object.value.slice(0, object.maxLength);
  }    
}
  
</script>
반응형
반응형

html 

<input type="radio" name="doughnut" id="doughnut" value="doughnut">
<label for="doughnut">도넛</label><br>

 

javascript

[이름이 doughnut인 label 선택해서 text 변경하기]

$("label[for = 'doughnut' ]").text("맛있어");

 

반응형

+ Recent posts