전체 (67)
web sequence diagram 오픈

Web sequence diagram 오픈


온라인으로 다이어그램을 쉽게 그려준다

사실 다른 사이트꺼 가져다가 한글 오류 수정하고 쓰기 편하게 바꿈


http://wsd.donnert.net

'개발' 카테고리의 다른 글

web sequence diagram 오픈  (0) 2018.07.10
딴짓 오픈  (0) 2018.06.28
이클립스 플러그인 추천  (0) 2014.02.20
SecureCRT 한글 깨짐  (0) 2013.11.27
[HTML] 기본 context 경로 지정하기  (0) 2013.05.21
웹 포토샵  (0) 2012.01.18
0  Comments,   0  Trackbacks
댓글 쓰기
딴짓 오픈

여러 커뮤니티들의 인기글 링크 제공


리액트와 코틀린 공부도 할겸 제작

혼자 필요한 기능 넣으면서 잘 사용중

(현재 클리앙,웃대,엠팍,펨코,딴지,인스티즈,보배 지원)


http://ddanzit.donnert.net

'개발' 카테고리의 다른 글

web sequence diagram 오픈  (0) 2018.07.10
딴짓 오픈  (0) 2018.06.28
이클립스 플러그인 추천  (0) 2014.02.20
SecureCRT 한글 깨짐  (0) 2013.11.27
[HTML] 기본 context 경로 지정하기  (0) 2013.05.21
웹 포토샵  (0) 2012.01.18
0  Comments,   0  Trackbacks
댓글 쓰기
스프링 부트+마이바티스에서 트랜잭션이 안먹을때

@Transactional(rollbackFor = Exception.class)


1. rollbackFor를 명시해준다

2. 메소드는 public으로 선언해준다


다른 패키지에서 안쓴다고 public으로 안했다가 삽질 경험

그 외에 다른 DataSourceTransactionManager니 @EnableTransactionManagement니

이런거 안넣어도 잘 동작함(블로그 글 기준)


[개발/JAVA] - 스프링 부트(Spring boot)에서 mybatis(oracle) 적용하기


참고

https://stackoverflow.com/questions/7085271/how-to-set-up-transaction-with-mybatis-and-spring



0  Comments,   0  Trackbacks
댓글 쓰기
코틀린으로 스프링 사용 시 ClassNotFoundException: kotlin.reflect.full.KClasses

Caused by: java.lang.ClassNotFoundException: kotlin.reflect.full.KClasses

at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_151]

at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_151]

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[na:1.8.0_151]

at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_151]

... 26 common frames omitted


코틀린으로 스프링을 사용 시 위와 같이 오류가 난다

이 경우 kotlin-reflect을 추가해주면 간단히 해결


<!-- https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-reflect -->

<dependency>

    <groupId>org.jetbrains.kotlin</groupId>

    <artifactId>kotlin-reflect</artifactId>

    <version>1.2.41</version>

</dependency>



0  Comments,   0  Trackbacks
댓글 쓰기
H2 DB 사용 중 file is locked 발생

H2 DB를 사용 시 다음과 같은 오류 메세지를 만날때가 있습니다


The file is locked


내용 보면 알겠지만 여러 프로세스에서 동시에 접근할때 발행하는 오류입니다

제 경우 API 서버를 띄워놓고 배치를 돌릴때 이미 DB를 사용중이기 때문에 발생한 경우였습니다.

그럴 경우 설정을 다음과 같이 변경해 주시면 두개의 프로세스에서 동시 접근이 가능합니다.


datasource:
# url: jdbc:h2:file:~/test
url: jdbc:h2:~/test;AUTO_SERVER=true
username: sa
driver-class-name: org.h2.Driver


0  Comments,   0  Trackbacks
댓글 쓰기
합정 라멘집 길라멘

지나가다 새로 생겼길래 들러본집


메뉴 및 안내





라멘/미니차슈덮밥/반찬







외관

바 형식으로 먹는 공간이라 자리가 협소할 수 있음

테이블이 있는지는 모르겠음

전체적인 분위기는 깔끔


총평

국물이 굉장히 무거운 느낌의 맛이 납니다.

초중반까지는 좋으나 먹다보면 좀 느끼한 느낌이 날수도 있습니다

그럴때 마늘을 넣어주시면 다른 맛을 느낄수 있음.

설명에도 써있지만 국물맛이 확 변하기 때문에 먹다가 넣으세요.

미니덮밥은 소소.


결론은 돼지육수 좋아하시면 추천

아니면 라멘트럭을 추천

오레노라멘도 맛있다고 하더라구요



위치

은하수다방(이전 후)이 있는 합정동 뒷길에 위치해 있습니다

도로가가 아니라 골목 안쪽으로 가야하니 잘 찾아보세요


이 장소를 Daum지도에서 확인해보세요.
서울 마포구 합정동 368-51 1층 | 길라멘
도움말 Daum 지도

'맛집' 카테고리의 다른 글

합정 라멘집 길라멘  (0) 2018.05.04
상수 라멘트럭  (0) 2016.10.10
아우라지 삼산점  (0) 2016.10.07
더 파스텔라(THE PASTELA!)  (0) 2016.09.18
명동교자  (0) 2016.09.12
0  Comments,   0  Trackbacks
댓글 쓰기
spring profile 사용시 주의점

최근 삽질


application.yml에 값을 설정 해두고

spring:
profiles: local
sleep:
min: 100
max: 500
---

spring:
profiles: dev

sleep:
min: 500
max: 1000


application.properties에 아래와 같이 프로파일을 설정해주었다

spring.profiles.active=dev


어플리케이션 구동했으나 계속 발생하는 오류.  심지어 다른 서버에서는 정상 동작


org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sleepAspect': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'sleep.min' invalue "${sleep.min}"


오류를 유심히 보니 프로파일이 다른것으로 적용이 되고 있었음
INFO(6347)[main] [n.d.TestApplication:656] The following profiles are active: dev1


원인은 서버 환변경수에 다음과 같이 프로파일이 적용되고 있었음

$ env | grep PROFILE

SPRING_PROFILES_ACTIVE=dev1


결론은 프로퍼티보다 서버 환경변수의 값이 먼저 적용하기 때문에 쉘 스크립트에서 환변경수를 초기화

프로그램안에만 적용되기 때문에 다른 프로그램에는 영향 없음

SPRING_PROFILES_ACTIVE=

nohup java -cp application.properties -jar donnert.jar > console.log 2>&1 &



0  Comments,   0  Trackbacks
댓글 쓰기
@Scope 어노테이션 사용하기(request+ProxyMode)

[개발/JAVA] - Threadlocal을 이용하여 사용자별 요청 처리하기


ThreadLocal과 같이 보시면 좋습니다.

스프링에서 빈 Scope 타입은 여러가지 방식이 있으며 아래를 참고해 주세요.

https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html


별도의 옵션이 없다면 빈은 싱글톤으로 관리되며 부모의 속성을 따라갑니다.

즉 controller는 따로 설정을 하지 않았기 때문에 singleton으로 동작하게 되며 그 안에서 주입받은 빈 역시 scope를 request로 줘도 singleton으로 동작하게 됩니다.

빈을 생성해 주고 위에 보이는것처럼 scope를 request로 선언해줍니다. 


그리고 위처럼 컨트롤러를 구현합니다.

위 경우 Cart가 매 요청마다 생성될것 같지만 이미 Controller(부모)가 싱글톤으로 잡혀있고 빈을 주입받은 상태이기 때문에 Cart 역시 싱글톤으로 동작합니다.  결국 Cart와 Mart는 동작 상 다른 점이 없습니다.


이럴땐 아래처럼 ProxyMode를 지정하게 되면 싱글톤 객체를 중간 프록시에서 새로운 오브젝트로 전달을 해주게 됩니다.

이전 글에서 Threadlocal을 이용했지만 스프링의 빈 만으로도 쉽게 개발이 가능합니다.


https://github.com/donnert/spring-boot/tree/master/scope-proxy

0  Comments,   0  Trackbacks
댓글 쓰기
Threadlocal을 이용하여 사용자별 요청 처리하기





개발시 소스 전체에서 사용할 수 있는 전역변수처럼 데이터를 할당하고 싶을떄가 있습니다.

Threadlocal을 이용하여 이를 구현해 봅니다.


ShoppingController.java

@RestController
public class ShoppingController {

	private int melon;

	@RequestMapping("/")
	private String test() {
		this.addMelon();
		
		return String.valueOf(melon);
	}
	
	private void addMelon() {
		melon++;
	}
}

사용자별로 요청 시 카트에 멜론을 담는 기능을 구현하려고 합니다.  이 떄 카트 수량은 여러 메소드에서 사용할 수 있기 때문에 멤버변수로 선언을 합니다.


이렇게 작성 후 실행을 해보면 카운트가 초기화가 되지 않고 계속 증가하는 것을 볼 수 있습니다.  스프링의 경우 빈 관리를 싱글톤으로 하기 때문에 ShoppingController 객체는 요청 시 재사용 됩니다.  멤버변수 역시 초기화가 되지 않습니다.




아래는 Threadlocal을 이용해 사용자별 카트를 구현한 소스입니다.


ThreadRepository.java

public class ThreadRepository {
	private static ThreadLocal<Cart> threadLocal = new ThreadLocal<Cart>() {
		@Override
		protected Cart initialValue() {
			return new Cart();
		};
	};
	
	public static Cart getCart() {
		return threadLocal.get();
	}
	
	public static void remove() {
		threadLocal.remove();
	}
}

카트를 담을 저장소를 만들어 줍니다.  Thradlocal을 이용하여 Thread별로 저장소가 생성이 됩니다.


Cart.java

public class Cart {
	private int apple = 0;
	private int orange = 0;
	private int melon = 0;
	
	public void addApple() {
		this.apple++;
	}

	public void addOrange() {
		this.orange++;
	}

	public void addMelon() {
		this.melon++;
	}

	@Override
	public String toString() {
		return "Cart [apple=" + apple + ", orange=" + orange + ", melon="
				+ melon + "]";
	}
}

카트를 생성해줍니다.


ShoppingController.java

@RestController
public class ShoppingController {

	@RequestMapping("/")
	private String test() {
		ThreadRepository.remove();
		
		this.addMelon();
		
		return ThreadRepository.getCart().toString();
	}
	
	private void addMelon() {
		ThreadRepository.getCart().addMelon();
	}
}

컨트롤러가 위처럼 수정되었습니다.  ThreadRepository에서 getCart를 했을때 해당 요청 쓰래드에 대한 Cart가 나오기 때문에 소스 어떤부분에서든 해당 카트의 데이터를 넣고 빼는 것이 가능합니다.

이때 ThreadLocal을 이용하였기 때문에 요청 시 새로운 스래드가 생성되며 그 스래드에서만 사용할 수 있게 관리됩니다.


* 일반으로 WAS는 쓰래드풀을 쓰기 때문에 요청이나 응답 시 해당 Threadlocal을 초기화 하지 않을 경우 이전에 사용한 정보가 남아 있습니다.  쓰래드 재사용시 반드시 remove를 통해 초기화 시켜주어야 합니다.



참고소스

https://github.com/donnert/spring-boot/tree/master/thread-local




0  Comments,   0  Trackbacks
댓글 쓰기
한글 byte로 자르기(깨짐 없이)

쓸때마다 새로만드는 것 같아서 저장용


UTF-8일 경우

subStringBytes("블라블라블라라", 10, 3);

EUC-KR일 경우

subStringBytes("블라블라블라라", 10, 2);


public String subStringBytes(String str, int byteLength, int sizePerLetter) {
	int retLength = 0;
	int tempSize = 0;
	int asc;
	if (str == null || "".equals(str) || "null".equals(str)) {
		str = "";
	}

	int length = str.length();

	for (int i = 1; i <= length; i++) {
		asc = (int) str.charAt(i - 1);
		if (asc > 127) {
			if (byteLength >= tempSize + sizePerLetter) {
				tempSize += sizePerLetter;
				retLength++;
			}
		} else {
			if (byteLength > tempSize) {
				tempSize++;
				retLength++;
			}
		}
	}

	return str.substring(0, retLength);
}


0  Comments,   0  Trackbacks
댓글 쓰기