2016년 8월 24일 수요일

리액트 핵심정리를 접고 프로 리액트를 새로 읽습니다.

초심자가 읽기엔 리액트 핵심정리는 이해가 난해한듯하여(지극히 주관적임)
프로 리액트를 처음부터 읽는데...

리액트 커뮤니티에서는 웹팩이라는 도구를 선호한다고 설명합니다.

부록 A에 웹팩이라는 도구의 사용법부터 안내합니다 (상세해서 좋네요)


그중에 바벨이라는 로더? 설치부터 장문의 명령을 사용합니다 ㅋㅋ

npm install --save-dev 
babel-core
babel-loader
babel-preset-es2015
babel-preset-react

--save-dev는 해당 프로젝트 내에서 사용할것이니 node_module에  설치됩니다.


부록A 웹팩을 따라가던중

ERROR in ./~/css-loader!./app/main.css
Module build failed: ReferenceError: Promise is not defined
    at LazyResult.async (/home/sharpscar/workspace/react/pro/node_modules/css-loader/node_modules/postcss/lib/lazy-result.js:237:31)
    at LazyResult.then (/home/sharpscar/workspace/react/pro/node_modules/css-loader/node_modules/postcss/lib/lazy-result.js:141:21)
    at processCss (/home/sharpscar/workspace/react/pro/node_modules/css-loader/lib/processCss.js:198:5)
    at Object.module.exports (/home/sharpscar/workspace/react/pro/node_modules/css-loader/lib/loader.js:24:2)
 @ ./app/main.css 4:14-75


이라는 에러를 맞닥드린다.

https://github.com/webpack/css-loader/issues/144

비슷한 증상이다.

https://github.com/stefanpenner/es6-promise



HMR
웹팩과 바벨은 서로 다른 별개의 도구이다.
HMR은 컴포넌트의 코드를 수정할때 브라우저에서 실시간으로 컴포넌트를 업데이트 할 수 있는 웹팩 플러그인이며, 제대로 작동하려면 모듈에 특수한 코드를 추가해야 한다.


1장 시작하기를 따라하는데
ERROR in ./source/App.js
Module build failed: SyntaxError: Unexpected token (7:6)

   5 |   render(){
   6 |     return (
>  7 |       <h1>Hello World!</h1>
     |       ^
   8 |     );
   9 |   }
  10 | }

 @ multi main
webpack: bundle is now VALID.
계속 이런 에러가 나온다.  jsx 는 자바스크립트 내부에 xml  , html 문법을 사용할수 있는데
설정에 문제가 있는것일까?

기존 소스의  package.json 파일을 복사하여
프로젝트폴더에서 npm install로 새로 설치하여 시작함


----------------------------------------------------

bundle.js:21492 Uncaught TypeError: Cannot read property 'filter' of undefined
해당 부분을 살펴보면

기존의 KanbanBoard.js의 render() 부분에서 뭔가 오타를 적은게 아닐까 의심된다.

해결)

app.js의 마지막줄에

render(<KanbanBoard cards={cardsList} />, document.getElementById('root')); 에서

render(<KanbanBoard />, document.getElementById('root'));

부분 누락
역시 코드를 배끼는것도 차분한 성격이 유리하다. 덤벙대는 성격은 전혀 도움이 안됨.


bundle.js:1322 Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `List`. See https://fb.me/react-warning-keys for more information.

리액트 매뉴얼에서 해당내용을 해석하고 문제점을 찾아보려 했지만 무슨내용인지 이해가 잘 안된다.


// WRONG!
var ListItemWrapper = React.createClass({
  render: function() {
    return <li key={this.props.data.id}>{this.props.data.text}</li>;
  }
});
var MyComponent = React.createClass({
  render: function() {
    return (
      <ul>
        {this.props.results.map(function(result) {
          return <ListItemWrapper data={result}/>;
        })}
      </ul>
    );
  }
});
// Correct :)
var ListItemWrapper = React.createClass({
  render: function() {
    return <li>{this.props.data.text}</li>;
  }
});
var MyComponent = React.createClass({
  render: function() {
    return (
      <ul>
        {this.props.results.map(function(result) {
           return <ListItemWrapper key={result.id} data={result}/>;
        })}
      </ul>
    );
  }
});
 The situation gets more complicated when the children are shuffled around (as in search results) or if new components are added onto the front of the list (as in streams). In these cases where the identity and state of each child must be maintained across render passes, you can uniquely identify each child by assigning it a key:

When React reconciles the keyed children, it will ensure that any child with key will be reordered (instead of clobbered) or destroyed (instead of reused).

The key should always be supplied directly to the components in the array, not to the container HTML child of each component in the array:



자식 컴포넌트가  섞일수 있는데 key를 사용하는 방법에 대해 말하는듯하다 
컴포넌트에 직접적으로 제공되어야지 html자식요소의 배열에 넣으면 안된다는것같은데
추후 또 같은 에러가 발생하면 다시 찾아봐야할것같다. 칸반보드에 시간을 너무 빼앗기는듯하다.

2016년 8월 18일 목요일

React.js 핵심정리 - 테크 트랜스 그룹 T4 번역

이 그룹? 이 단체에서 번역한 서적을 두번째 접하는데

공통적으로 느끼는게 대체 무슨소리하는지 전혀 감이 안잡힌다.


번역을한 내용을 읽어보면 아 이런내용이구나 라고 딱 머리속에 개념이 잡혀야되는데
읽을수록 뜬구름 속에서 헤매이는 느낌이라고 해야되나?



최근 개발 이슈나 기술들이 번역되어서 한국어판으로 나오는데 대다수가 직접 원어를 해석해서
기술습득을 하는것인지 ...



React.js  핵심정리 지금까지 발견된 오타

85페이지 15째줄은 CollectionRenameForm과 CollectionExportForm  으로 정정되어야 할것이고

92페이지  onRemoveTweetFromCollection과 onRemoveAllTweetsFromCollection함수는
 이라고 정정되어야 할것이다.

분명 책을쓴 저자는 기술에대해 정보를 공유하고자 노력하여 나온 결과물인데
이런식으로 이해를 방해하는 내용들이 많으면 공부의지가 꺾인다.

소스코드 또한 누락된 부분이 있다. 75, 78, 79페이지  업로드된 소스코드를 참조하면 될일이긴 하지만...

책을 출판하기 전에 원서를 보지않고 번역서만 보고 직접 실습을 해보고 출간되었으면 좋겠다 .
(당연한 이야기겠지만 번역서만 보고 실습이 원활이 진행되지 않는다면 문제가 있는것이다.)

좀더 세심한 번역을 해주었으면 좋겠다.


90페이지 1번
1. 부모 컴포넌트는 콜백함수를 프로퍼티로 해 자식 컴포넌트에 전달한다. 자식컴포넌트는 이 콜백함수를 this.props 변수로 접근할수 있다.

여기서 프로퍼티로 해? 프로퍼티로 해서? 아니면 해를 아예 무시해야되나?

부모컴포넌트는 콜백함수를 프로퍼티로 자식 컴포넌트에 전달한다. - 프로퍼티를속성으로 고쳐보자

부모 컴포넌트는 콜백함수를 속성으로  자식 컴포넌트에 전달한다.  자식 컴포넌트는 이 콜백함수를 this.props변수로 접근할수 있다.

좀더 매끄럽지 않나? 별로 중요하지않은 '해' 한글자로 중요한 뒷내용이 이해가 어려워진다면 과감하게 삭제될필요가 있지않은지..

React.js 핵심정리 1일차

 음 1일차 이렇게 써넣으니 뭔가 학습하는것 같군요

실습을 해보시면 아마 1장부터 막히실겁니다. (저는 그랬습니다..)

트위터 가입후 키를 받고 config.json? 작성하고

npm start! 하면

 > snapkite-engine@0.1.2 start /home/sharpscar/workspace/react/snapkite-engine
> node app.js

[Snapkite][Socket] Listening on port 3000

이렇게 나오는데요

localhost:3000으로 접속해봐도 아무 응답이 없더라구요 ...

찾아보니 쓰신분이 http-server를 설치해서 8080으로 접속하는걸 유도하시는듯...

https://github.com/fedosejev/react-essentials/issues/46


어쨋든 http-server로해보면 index.html이 나오는것은 확인할수 있습니다.
(트위터에 가입해보고 키 인증하고 한것은 나중에 쓸데가 있겠지요;)

어쨋든 국내서적으로 53페이지의 2번단락의
document.getElementById( '') 에서
react-application이라고 해야 나옵니다. 사실 당연한거지요 index.html에 react-application이라고 작성했으니 그렇게 해야 정상적으로 나옵니다.
번역하신분이 작은것은 그냥 넘어가버리는 쿨한 성격이신듯 합니다.

계속 고고!


아 이쯤되면 슬슬 욕이 올라온다.

제발 원서에 있는 소스좀 빼먹지좀 말아줬으면 좋겠다

에러뜨면 어느라인인지 찾기도 어려운데 소스코드 빠진것도 있고 변경된것도 있다.

차라리 소스코드 내용은  지우고 업로드된 소스코드를 참조하세요 라고 적어놓는게

독자에게 더 친절한 안내가 되지않을까?

2016년 8월 16일 화요일

스프링 퀵스타트 4 일차 -2

 4일차에서 다 끝내지 못하고 다음날로 이어졌다.
ㄴㄴ

HTTP Status 500 - javax.servlet.ServletException: javax.servlet.jsp.JspTagException: No message found under code 'message.user.login.language.en' for locale 'ko_KR'.

페이지 446에서 index.jsp를 실행시켰으나 나오는에러다.

해결)

말그대로 해당위치의
/src/main/resources/message/messageSource_en.properties 파일내에
message.user.login.language.en=영어
message.user.login.language.ko=한글

내용이 잘못되어있었다.

message.user.loginlanguage.en=영어
message.user.loginlanguage.ko=한글

수정후 확인 인코딩이 문제가 됨

음...

properties 파일  한글로 작업하면 무슨 16진수같은게 나와서
잔머리를 굴려 propedit 인가 일본사람이 만든거같은데 설치해보니 한글도 매우 잘나와
사용해봤다. 그런데.... 막상 index.jsp를 실행해보면 글씨가 ??? 이런식으로 깨져서나온다.

그래서 설치된 플러그인을 제거하고 다시 실행해보니

org.springframework.beans.factory.CannotLoadBeanClassException

전에 나오지도 않았던 에러가 나온다. 클래스를 찾을수 없다고 한다.
Caused by: java.lang.ClassNotFoundException: com.springbook.biz.user.impl.UserServiceImpl

그래서 aplicationContext.xml 의 해당내용에서

<bean id="userService" class="com.springbook.biz.user.impl.UserServiceImpl">
        <property name="userDAO" ref="userDAO"/>
    </bean>

클래스부분을 싹 지우고 다시UserServiceImpl 부분만 재작성하고 ctrl+1 을 사용해서 다시 지정해주고 저장

다시실행하면 잘된다.

이유는 모르겠다. 어쨋든 잔머리 굴리지말고, 손가락보다는 ctrl+1을 믿어라

그리고 에러 메시지를 읽는 눈을 더 키워라

pom.xml을 수정하다가 갑자기 applicationContext에 에러가 있다는것을 발견했다.

transaction설정부분과 spring jdbc설정관련 해서
2개의 클래스를 못찾고 있었다.  - 관련 jar는 commons-dbcp-1.4.jar 인데
pom.xml에서 dependency부분을 추가하거나 제거하면 관련 라이브러리를 가져오거나 제거한다.

그런데 계속 못찾는다. 몇번을 다시써보고, 해결방안을 찾아보려해도 찾을수가없다.


pom.xml을 수정할땐 조심하자 정말 설정파일이 잘못 틀어지면 다시 제대로 돌리기 어렵다.

class not found org.apache.commons.dbcp.BasicDataSource

해당에러로 굉장히 많은 시간을 소모했다.

서버를 재시작하면 계속 해당 클래스를찾을수 없으니 빨리 찾아라 라고 에러메시지를 길게 뽑아내서 직접 관련 jar파일을 넣어줘도 보고비슷한 사례가 어떤게 있나 찾아봤다

pom.xml에서 관련내용을 지웠다가 저장하고 다시붙여넣으니까 잘된다.

이게 정말 싫은부분이다. 어디서 자동으로 받아온jar파일이 손상된게 아니라면 왜 이런일이 발생해서 속을 썩일까? ㅠㅠ


490페이지 마이바티스 설정까지 해보았다.

음 정말 프레임워크를 사용해보면 설정만 잘하면 매우 쉽게 코딩이 가능하다.

13:40:20.071 [main] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
13:40:20.140 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
13:40:20.140 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
13:40:20.140 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
13:40:20.140 [main] DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
13:40:20.205 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection
13:40:20.253 [main] DEBUG o.a.i.d.pooled.PooledDataSource - Created connection 1604125387.
13:40:20.253 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [conn0: url=jdbc:h2:tcp://localhost/~/test user=SA]
13:40:20.255 [main] DEBUG BoardDAO.getBoardList - ==>  Preparing: SELECT * from board where title like '%'||?||'%' order by seq desc
13:40:20.290 [main] DEBUG BoardDAO.getBoardList - ==> Parameters: (String)
13:40:20.338 [main] DEBUG BoardDAO.getBoardList - <==      Total: 6
--->BoardVO [seq=6, title=작성자는 왜, writer=gksrmf dksTJwj, content=한글 안된다고등록했다, regDate=Tue Aug 16 00:00:00 KST 2016, cnt=0]
--->BoardVO [seq=5, title=아무것도 하기싫다, writer=나, content=정말 아무것도 하기싫고
보기도 싫고

이꼴저꼴 보기싫다는게 이런거구나, regDate=Tue Aug 16 00:00:00 KST 2016, cnt=0]
--->BoardVO [seq=4, title=가입인사 -수정, writer=아무무, content=잘부탁드립니다 -수정, regDate=Tue Aug 16 00:00:00 KST 2016, cnt=0]
--->BoardVO [seq=3, title=아니 이게 된다고?, writer=브론즈, content=브론즈 실버가 가장 많이 말하는 단어
"아니 x발", regDate=Tue Aug 16 00:00:00 KST 2016, cnt=0]
--->BoardVO [seq=2, title=두번째글등록, writer=등록자, content=작성내용, regDate=Tue Aug 16 00:00:00 KST 2016, cnt=0]
--->BoardVO [seq=1, title=bb, writer=bb, content=bb, regDate=Tue Aug 16 00:00:00 KST 2016, cnt=0]



결국 전부 읽고 실습해 보았다.

잠시 다른 자바 서적을 읽고 다시 실습해보면 좀더 깔끔하게 책 내용을 이해할수 있을것같다.

2016년 8월 15일 월요일

스프링 퀵스타트 4 일차

3일정도 쉬었다.

다시 보려니까 기억이 가물가물...

페이지 349부터 기존의 스프링 MVC 방식의 게시판을

어노테이션 방식으로 수정하는 작업을 해보고 있는데

presentation-layer.xml에서  컨텍스트 NS를 등록 하는것부터 시작한다.

여기서 뭔가 오타가 있었는지 ... 이런 에러를 내뿜는다.

java.lang.NoClassDefFoundError

에러가 발생한곳을 따라가보니 InsertBoardController에서 호출하는
BoardDAO의 insertBoard 메서드의
JDBCUtil.close(stmt,conn);
이부분을 가리키며 NoClassDefFoundError를 표시하고있다.

내생각엔 presentation-layer에서
<context:component-scan base-package="com.springbook.view">

여기서 view만 가리키고   com.springbook.biz는 안가리켜서 그런게 아닐까 하고 의심하여
(여기서 가르키는 부분의 객체를 생성한다고 설명되어있으니...)

com.springbook.biz도 추가하거나 com.springbook 까지만 입력해 보았는데

이번엔 beansfactory.NoSuchBeanDefinitionException이 뜬다

관련에러를 찾아보니까 @Service를 잘못 설정해줬다는 의견들이 많다

흠 그래서 다시 com.springbook.view로 고쳐주고 다시 실행해봤는데 정상적으로 글이 등록
되버렸다. 뭘까? 원인도 못찾고 그냥 에러메시지가 없어져버리니까 뭔가 겁이난다.

왜그런 에러메시지가 나왔던걸까?



결국 비슷한 내용이 402페이지에 설명되어있다.

사용자 요청이 들어오면

DispatcherServlet은 presentation-layer.xml을 로딩하고

스프링컨테이너를 구동한다.

이때 BoardController객체만 메모리에 생성되고 @Autowired로 의존성 주입할 BoardServiceImpl객체는 생성되지않는다

boardcontroller보다 의존성 주입될 boardServiceImpl객체가 먼저 생성되어 있어야 한다.



406페이지까지 - ContextLoaderListener 를 프리로딩 하여 나오는 결과를 볼수있었다.
로그
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Tue Aug 16 12:52:13 KST 2016]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml]
INFO : org.springframework.context.support.PropertySourcesPlaceholderConfigurer - Loading properties file from class path resource [config/database.properties]
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 964 ms
8월 16, 2016 12:52:14 오후 org.apache.coyote.AbstractProtocol start
정보: Starting ProtocolHandler ["http-nio-8080"]
8월 16, 2016 12:52:14 오후 org.apache.coyote.AbstractProtocol start
정보: Starting ProtocolHandler ["ajp-nio-8009"]
8월 16, 2016 12:52:14 오후 org.apache.catalina.startup.Catalina start
정보: Server startup in 1976 ms
8월 16, 2016 12:53:02 오후 org.apache.catalina.core.ApplicationContext log
정보: Initializing Spring FrameworkServlet 'action'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'action': initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'action-servlet': startup date [Tue Aug 16 12:53:02 KST 2016]; parent: Root WebApplicationContext
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/config/presentation-layer.xml]

INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/deleteBoard.do] onto handler 'boardController'
INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/updateBoard.do] onto handler 'boardController'
INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/insertBoard.do] onto handler 'boardController'
INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/getBoard.do] onto handler 'boardController'
INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/getBoardList.do] onto handler 'boardController'
INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/login.do] onto handler 'loginController'
INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/logout.do] onto handler 'logoutController'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'action': initialization completed in 158 ms

2016년 8월 10일 수요일

스프링 퀵스타트 3일차

<td align="left"> <a href="getBoard.jsp?seq= <%=board.getSeq() %>"><%=board.getTitle() %></a></td>

이게 무엇인 아시는분?

모델1방식의 게시판을 만드는소스의

 게시물 리스트에서 제목에 해당하는 한줄 소스다.

차라리 board.getSeq() 의 값을 변수에 넣어놓고 글번호에도 쓰고 저기도 쓰고 하면 좋을것 같은데..

자바를 배웠다가 다시 php를 배웠다가 다시 자바를 공부하는 중에 느끼는게

jsp 예제들 대부분 jsp 페이지 내에서 테이블의 요소요소 들의 크기를  페이지 내에서 정의한다
 그것도 딱 100 150 100 200 이런식으로

css파일을 만들고 적용하는것까지 하면 좋을것같은데  그럼 분량이 어마어마해지려나

아니면 관련 css파일은 따로 업로드 해두었으니 적용하시는게 좋을거요 라고 협박을 하는것도 좋을것같은데 ㅎㅎ



근데 저 소스를 다시봐도 어지럽다 저런소스를 '잘못된부분이 있으니 유지보수 하시오 '

이런 미션이 떨어지면 정말 난감할듯 ㅋㅋ


그런데 정말 일어났습니다.

java.lang.NumberFormatException: For input string: " 24"

자세히보면 24 앞에 공백문자가 하나 들어가 있습니다.

변경전
<a href="getBoard.jsp?seq= <%=board.getSeq() %>"><%=board.getTitle() %></a></td

변경후
<a href="getBoard.jsp?seq=<%=board.getSeq()%>"><%=board.getTitle()%></a>

파라미터에 공백문자 스페이스 하나가 들어가 있어서

    vo.setSeq(Integer.parseInt(seq));  라인의
java.lang.NumberFormatException: For input string: " 24" 예외가 계속 발생합니다
널과 관련될 경우가 크다고 합니다.  제경우엔 파라미터에 공백이 섞여 들어가서 발생했습니다.


참고로 위의 파라미터의 공백은 trim()으로도 제거안되며
str.replaceAll("(^\\p{Z}+|\\p{Z}+$)", "");  으로도 제거 안됩니다.

그냥 파라미터에 공백이 들어가지 않게 만전을 기하십시오


3일차 약간 쉬엄쉬엄했지만 모델2 페이지 284까지 읽고 실습했다.

하루하루 따라가는 기분이 좋다.  이책의 장점은 하루 읽고 실습하는양이 정해져있어
농땡이 피우기가 힘들다

만족



public class HandlerMapping {

    private Map<String, Controller> mappings;
   
    public HandlerMapping(){
        mappings =  new HashMap<String, Controller>();
        mappings.put("/login.do", new LoginController());
    }

여기 mappings라는 변수는 맵으로 선언되어있는데
해쉬맵을 생성해서 mappings라는 변수에 넣으려하니까
type mismatch라고 에러가난다. 형변환을 해주든지 아니면 선언을 해쉬맵으로 하라고 이클립스는 해결방법을 제시한다.

일단 형변환으로 해본다.

해결)
import java.util.Map
import java.util.hashMap
임포트를 안해서 발생한 오류


페이지 310
javax.el.PropertyNotFoundException: Property 'seq' not found on type java.lang.String
 
 
org.apache.jasper.JasperException: An exception occurred processing JSP page /getBoardList.jsp at line 48

45:    
46:    <c:forEach items="${boardList} " var="board">
47:    <tr> 
48:     <td>${board.seq }</td>
49:     <td align="left"> <a href="getBoard.do?seq=${board.seq }">${board.title}</a></td>
50:     <td>${board.writer }</td>
51:     <td>${board.regDate }</td>
 
 
 48번라인의 board.seq를 자바.랭.스트링 에서 찾을수 없다 라고 말한다.
 
해결)
 
문제는 상단에 
<c:forEach items="${boardList} " var="board"> 여기 있다.
 
boardList} 공백 " 
 
공백이 제일 무섭다. 공백이 척결대상 1호다.  


321페이지

메시지확인

INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'action': initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'action-servlet': startup date [Thu Aug 11 15:32:03 KST 2016]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/config/presentation-layer.xml]
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'action': initialization completed in 216 ms
WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/BoardWeb/login.do] in DispatcherServlet with name 'action'

이전에 DispatcherServlet을 직접 구현하여 사용했을때와

스프링 프레임워크의 mvc 의 DispatcherServlet을 사용하기위해 세팅을 한것을 비교

DispatcherServlet은 클라이언트의 요청처리에필요한 HandlerMapping, Controller, viewResolver객체들을 생성하기위해 스프링 컨테이너
XMLWebApplicationContext컨테이너를 구동한다.

상기한 3개의 객체들을 생성하기위해 스프링 컨테이너를 구동하는데 세팅을
WEB-INF/config/presentation-layer.xml에 넣어놓고  서버를 재시작 후에 로그인하면
위의 메시지 스프링 설정파일이 로딩된것을 확인할수있다. 


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
 
  <filter>
      <filter-name>characterEncoding</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
          <param-name>encoding</param-name>
          <param-value>EUC-KR</param-value>
      </init-param>
  </filter>
 
  <filter-mapping>
      <filter-name>characterEncoding</filter-name>
      <url-pattern>*.do</url-pattern>
  </filter-mapping>
 

  <servlet>  
    <servlet-name>action</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/config/presentation-layer.xml</param-value>
    </init-param>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

인코딩 필터 *.do로 들어오는것은 다 euc-kr로 한글 인코딩 처리가 자동으로 된다



325페이지에서 com.springbook.view.controller 패키지를 삭제하라는데

왜이렇게 힘드냐

책보고 배낀 소스라할지라도 이렇게 손이 떨리는데 내가 직접만든 소스 백업도 안하고
그냥 삭제하라고하면 못할거같다.

스프링 퀵스타트 2일차

횡단관심과 핵심관심


공통으로 동작하는 비즈니스 로직 로깅, 예외,트랜젝션을 횡단관심,

사용자의 요청에 따라 실제로 수행되는 핵심 비즈니스로직을 핵심관심이라 한다.

OOP에서 이 핵심관심과 횡단관심을 완벽하게 분리할수는 없지만

AOP는 이런 OOP의 한계를 극복할수있도록 도와준다.

스프링의 AOP는 클라이언트가 핵심관심에 해당하는 비즈니스 메소드를 호출할 때, 횡단 관심에 해당하는 메소드를 적절하게 실행해 준다. 이ㄸ 핵심관심 메소드와 횡단관심 메소드 사이에서 소스상의 결합은 발생하지 않으며, 이것이 우리가 AOP를 사용하는 주된 목적이다.

AOP의 핵심은 바로 애스팩트이다. 애스팩트는 포인트컷과 어드바이스의 결합으로서 어떤 포인트컷 메소드에 대해서 어떤 어드바이스 메소드를 실행할지 결정한다. 이 애스팩트 설정에 따라 AOP의 동작방식이 결정되므로 AOP용어중 가장 중요한 개념이라 할수있다.


199 페이지 Before 어드바이스

어노테이션을 이용한 어드바이스를 실습하는데 잘 안된다.

오타 확인도 했고 설정파일의 기존의 내용을 주석처리 했는데
알맞게 결과가 나오지 않는다

해결) 알고보니 applicationContext.xml에서
<aop:aspectj-autoproxy/>  구문이 사라져있다.
주석처리하면서 지워졌나보다

구문 삽입후 정상작동 확인.

어드바이스 메소드 중에서 유일하게 Around메소드에서만 JoinPoint가 아닌 ProceedingJoinPoint객체를 매개변수로 받는다 그래야 proceed()메소드를 이용하여 클라이언트가 호출한 비즈니스 메소드를 실행할 수 있기 때문이다.

2016년 8월 8일 월요일

java Spring 퀵 스타트 1일차

페이지 100 의 내용중에



의존성 주입 어노테이션 이라는 의존성 주입설정이 있다.

첫번째 @Autowired를 사용하는데

우선 sonySpeaker가 메모리상에 생성 되어야 한다. 내가 실습하는 동안 에러가 발생하였는데




Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private polymorphism.Speaker polymorphism.LgTV.speaker; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [polymorphism.Speaker] is defined: expected single matching bean but found 2: apple,sony
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 12 more

원인 부분만 보면 싱글 매칭이 예상되지만 2개를 찾았다. 애플, 소니

그러니까 설정파일에서 애플 스피커와 소니 스피커 두개가있는데 어느걸쓸거냐 라고 물어보는듯 하다.

애플스피커 내용을 xml설정 파일에서 지워주면 에러는 발새하지 않으나 만약 애플스피커커 객체를 메모리에 만들어놔야하는 경우도 있을것같다.

No qualifying bean of type [polymorphism.Speaker] is defined: expected single matching bean but found 2: sony,apple

좀더 읽어보니 이럴경우에는 @Qualifier를 사용하여 주입될 객체를 지정해주면된다.


실습중에 126페이지 보드의 비즈니스 로직에 관련하여 발견된 에러이다.

Exception in thread "main" java.lang.ClassCastException: com.springbook.biz.board.impl.BoardServiceImpl cannot be cast to com.springbook.biz.board.BoardService
    at com.springbook.biz.board.BoardServiceClient.main(BoardServiceClient.java:15)

해결 )

BoardSerivceImpl.java에서

public class BoardServiceImpl implements BoardService  

부분을 누락함  BoardService는 인터페이스인데 이부분을 누락하니까

형변환이 안된다고 에러를 보임.


실습중에  137페이지  유저 로그인 이 안된다

INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml]
INFO : org.springframework.context.support.GenericXmlApplicationContext - Refreshing org.springframework.context.support.GenericXmlApplicationContext@c2e1f26: startup date [Tue Aug 09 15:08:29 KST 2016]; root of context hierarchy
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
로그인 실패
INFO : org.springframework.context.support.GenericXmlApplicationContext - Closing org.springframework.context.support.GenericXmlApplicationContext@c2e1f26: startup date [Tue Aug 09 15:08:29 KST 2016]; root of context hierarchy




에러가 안나오며 그냥 로그인실패라고만 나온다. user가 널이란 얘긴데

이럴땐 어찌해야하는가 ㅠㅠ

해결)

이클립스에서 자동으로 생성되는 겟 메서드 기능을 이용하면

메서드 구문이 자동으로 완성된다.

그런데 문제는 메서드 안의 내용은 직접입력해줘야하는데 초보자인 나는 그냥 넘어가버렸다.

return 문에 적절한 내용을 넣지 않고 그냥   return null;

이렇게 되니 유저도 널 나도 널 시간도 널널하게 날아간다