블로그 이미지
Max.

calendar

    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Notice

2009.12.17 09:54 개발관련

기대하던 3.0이 힘들게 릴리즈 되었군요. 휴~ 저는 Spring Core는 어려워서, 모니터링 안하고 있습니다.  그래서, 얼마전에 3.0 RC3 버전의 레퍼런스 문서를 모두 출력했었죠. 이유는 이러다간 3.0을 잘못 사용해서 사람 여럿 다치게 하겠구나 하는 생각에서 였습니다. 출력해보니, 대략 800페이지가 넘는 분량입니다. 차근 차근 읽어볼 요량으로 아직 한달락도 읽지 못했는데, 오늘 보니 3.0 GA가 나와버렸군요. 출력한 종이에게 민망함을 느끼며서, 지난번 사내 스터디에서 진행하다 중단된 3.0 레퍼런스 학습을 다시 시작해야 겠습니다.

3.0 RC3 출력한 종이는 이면지로 잘 활용하고, 3.0GA 레퍼런스를 출력해야 겠습니다. 명석한(?) 머리 때문에 여럿 고생 합니다. ㅡㅡ;  (물론 Roo에도 Spring 3.0 GA가 반영되 었습니다. Rev #522)

이것으로 Spring 3.0.0 GA 출시 기념 Post 끝.



Changes in version 3.0.0.GA (2009-12-16)

* component scanning autodetects the new EE 6 "javax.annotation.ManagedBean" stereotype
* updated JPA 2.0 support to the final spec (tested compatibility with EclipseLink 2.0 GA)
* full support for GlassFish V3 GA (includes component scanning and load-time weaving)
* upgraded to JRuby 1.4 (while remaining compatible with JRuby 1.1 and above)
* bean property names are matched leniently ("title" and "Title"; "ISBN" and "iSBN")
* bean properties of type enum array/collection can be populated with comma-separated String
* removed getBeansWithAnnotation(Class,boolean,boolean) method from ListableBeanFactory
* PropertyPlaceholderConfigurer is compatible with Spring 2.5 extensions (again)
* SmartLifecycle beans will get auto-started on demand even if marked as lazy-init
* MBeanExporter detects FactoryBean-exported resources independent from declaration order
* refactored SpelExpressionParser to accept SpelParserConfiguration object with boolean flags
* revised TypeDescriptor's valueOf and forObject factory methods with some level of caching
* revised GenericConverter's "getConvertibleTypes" signature to return Set of ConvertiblePair
* GenericConversionService prefers matches against inherited interfaces over superclasses
* renamed ConverterRegistry's addGenericConverter(GenericConverter) method to addConverter
* no default converters for Object-to-Map and Map-To-Object anymore
* default converter for String-to-Properties parsing only applies for actual Properties objects
* default ObjectToStringConverter only stringifies objects that indicate proper toString behavior
* added "converters" property to FormattingConversionServiceFactoryBean as well
* full support for formatters and formatting annotations on array/collection elements
* no default number formatter (relying on plain java.lang.Number parsing and rendering)
* no default formatters for Date/Calendar (requiring explicit use of @DateTimeFormat)
* BeanValidationPostProcessor runs in before-initialization phase (before init methods) by default
* removed MultipartRequest mixin interface again (avoiding a package dependency cycle)
* revised RestTemplate method signatures to accept Object values instead of just Strings
* revised path variable extraction to properly deal with dots in variable values (again)
* reintroduced createBinder template method in Servlet/Portlet AnnotationMethodHandlerAdapter


 

저작자 표시
신고
posted by Max.
TAG 3.0, Spring
2009.11.18 15:46 개발관련

본 예시는, Spring Security 의 기본 User 정보를 확장하여, 도메인 특성에 맞는 정보를 포함시키는 예시이다. 최근 3.0버전에 맞췄으며, 특정 템플릿 만드는 도중에 주요 내용만 기록한다.

0. 환경
Window Vista + JDK1.6 + Tomcat6.0 + Spring3.0 RC1 + Spring Roo1.0 RC4 + Spring Security3.0 M2

1. applicationContext-security.xml 설정

<http auto-config="true" use-expressions="true">
     <form-login login-processing-url="/static/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t"/>
        <logout logout-url="/static/j_spring_security_logout"/>
        <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
        <intercept-url pattern="/project/**"  access="isAuthenticated()" />
        <intercept-url pattern="/member/**"  access="isAuthenticated()" />
       
        <intercept-url pattern="/resources/**" access="permitAll" />
        <intercept-url pattern="/static/**" access="permitAll" />
        <intercept-url pattern="/scripts/**"  access="permitAll" />
        <intercept-url pattern="/styles/**"  access="permitAll" />
        <intercept-url pattern="/images/**"  access="permitAll" />
        <intercept-url pattern="/remote/**"  access="permitAll" />
               
        <intercept-url pattern="/**" access="permitAll" />
    </http>
 <authentication-manager>
   <authentication-provider user-service-ref="webUserDetailsService">
     <password-encoder hash="plaintext"/>
   </authentication-provider>
 </authentication-manager>
 <beans:bean id="webUserDetailsService" class="net.max.core.security.service.WebUserDetailsService"/>

2. UserDetailsService 확장

public class WebUserDetailsService implements UserDetailsService {
 
 @Override
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
  boolean enabled = true;
  boolean accountNonExpired = true;
  boolean credentialsNonExpired = true;
  boolean accountNonLocked = true;
  List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
  AccountAuth accountAuth = null;
  WebUser webUser = null;
  
  try{
   accountAuth = (AccountAuth) AccountAuth.findAccountAuthsByLoginIdEquals(username).getSingleResult();
   authorities.add(new GrantedAuthorityImpl("ROLE_"+accountAuth.getAuthName()));
   
   Account account = (Account) Account.findAccountsByLoginIdEquals(username).getSingleResult();
   webUser = new WebUser(
     account.getStaffName(),
     account.getStaffClass(),
     account.getTeamId(),
     account.getEmail(),
     account.getPhone(),
     account.getMobile(),
     account.getPhoto(),
     account.getSignature(),
     account.getRoll(),
     account.getLoginId(),
     account.getLoginPw(),
     enabled,
     accountNonExpired,
     credentialsNonExpired,
     accountNonLocked,
     authorities    
     );
  }catch (Exception e) {
   throw new UsernameNotFoundException("Account user Not Founded");
  }
  
  if(webUser == null){
   throw new UsernameNotFoundException("Account user Not Founded");
  }  
  return webUser;
 }
}

3. UserDetails의 구현체인 User 클래스 확장

public class WebUser extends User {
 ...
 
 public WebUser(
   String staffName,
   String staffClass,
   Long teamId,
   String email,
   String phone,
   String mobile,
   String photo,
   String signature,
   String roll,
   String username, String password, boolean enabled,
   boolean accountNonExpired, boolean credentialsNonExpired,
   boolean accountNonLocked, List<GrantedAuthority> authorities
  ) {
  super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
  this.staffName = staffName;
  this.staffClass = staffClass;
  this.teamId = teamId;
  this.email = email;
  this.phone = phone;
  this.mobile = mobile;
  this.photo = photo;
  this.signature = signature;
  this.roll = roll;  
  this.loginId = username;
  this.loginPw = password;
  }
...
}



4. Web  Controller에서 사용시 예시

    @RequestMapping(value = "/project/doc/{projectId}/{docType}/{docId}/form", method = RequestMethod.GET)   
    public String createForm(@PathVariable("projectId") Long projectId, @PathVariable("docType") String docType, @PathVariable("docId") Long docId, ModelMap modelMap) {
...
     WebUser webUser = getWebUser();
...   
     doc.setAccountDepartment(webUser.getRoll());
     doc.setAccountName(webUser.getStaffName());
     doc.setAccountClassType(webUser.getStaffClass());
     modelMap.addAttribute("doc", doc);    
     return "project/doc/create";       
    } 
 
  private WebUser getWebUser(){
     return (WebUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    } 

기본적인 확장 예시이다. 이상 끝.

저작자 표시
신고

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

Spring Batch 2.1.0 예시  (0) 2009.11.18
Spring Quartz 예시(고전방식)  (0) 2009.11.18
Spring Secutiry3.0 확장 예시  (0) 2009.11.18
lock in  (0) 2009.11.13
JIRA 관련 링크 모음  (4) 2009.11.11
Spring Roo 1.0.0.RC3 Released  (0) 2009.11.11
posted by Max.
2008.12.13 13:07 이전글(~2009)

사실 KSUG가 커뮤니티 성격이라서, 여러가지를 병행할수 있지만, 지금은 포럼 위주라서 특정 주제에 대한 도배글이 염려스러워서 특정 주제로 학습을 한다면, 팀블로그가 좋을것 같다는 생각에 Spring Study Club (s2c) 이라는 팀블로그를 개설했다.

사용자 삽입 이미지


대부분 그렇지만, 스터디를 하겠다고 나선 사람들은 열정 지수가  높다. 좀더 적극적이고, 능동적인 태도가 초반에 활성화에 기여하는 부분이 많다. 그러나 역시 처음이다 보니 서로 적응하거나, 참여를 적극유도 하는데에는 여러가지 장벽을 겉어줘야 쉽게 뛰어 놀수 있으리라 생각했다. 따라서 초기 팀블로그를 개설하고, 멍석까지 깐 다음에 살짝 빠졌다. 언제까지 멍석이 필요할까 생각중 약간의 의견이 갈리기도 했지만, 결국 환경보다 이들의 의지에 의해서 좌우된것 같다. 아무리 노력해도 안할사람은 안하게 되고, 중도에 탈락자 등이 생기는건 어찌할수 없나보다.

지금은 봄싹이라는 모임을 기선씨가 잘 리드하고, 몇몇 열성적인 사람들이 잘 진행하고 있다. 지금 s2c는 어떤 장벽도 없다. 누구나 쉽게 팀블로그로 가입하고, 스터디를 생성하여 모임을 가질수 있다. 필요하다면, 언제든지 전문가(?)의 도움도 받을수 있으리라 생각된다.

신청하는것이 어떤 회사든 단체든 상관없이 스프링이란 것을 통해서 학습을 하길 원한다면, 이들의 노하우를 이용하는것도 좋을듯 하다.

스프링 학습을 어느정도 하다보면, 혼자해야하는 시기가 오거나, 스터디 학습의 효과가 떨어지다고 생각할수도 있을 것이다. 그러나 최근 3.0발표에서도 그렇듯 사실 스프링은 그 범위가 너무 방대하다. 당분간 스프링 스터디는 계속되어도 될만큼 스프링을 잘 안다고 말할수 없을것 같다.(사실 한번이라도 관련 데모를 만들어 돌려봤냐고 물어봐도 대답하기 어렵다.)

점점더 학습의 무게가 커지면 커질수록 여러사람이 학습한 내용을 공유하는 것의 힘은 커진다. 면대면으로 학습한것은 기억에도 오래남고, 질답으로 명쾌하게 속도 풀수 있으니, 일부러 시간을 내어 OFF 모임을 하는 효과는 충분히 있다고 생각한다.

사용자 삽입 이미지


스프링에 대해서 아무것도 모르다고 해도 s2c에서는 환영한다. 이미 잘 알고 있다고 해도 역시 환영할것이다. 스프링이라는 공유분모를 갖고 있는한 누구나 자유롭게 학습에 참여 할수 있으면 좋겠다. 물론 공짜다 ^^*

주위에 이 사이트를 모르고 있는 분이 계셔서 적는다는게 길어졌다. 내년엔 회사에도 적극적으로 알리고 참여를 독려할 예정이다. 사내 스터디와 사외 스터디는 성격도 많이 다르고, 그만큼 느끼는 자신감도 다르다. 겪어보면 새로운 열정을 느낄수 있을리라 생각된다. 아참 공짜 도메인을 준다고 하여 도메인도 하나 땄다. http://s2c.pe.kr ^^*

신고
posted by Max.
prev 1 next

티스토리 툴바