@ModelAttribute 을 이용하여 파라미터를 받아서 사용하다가

validation이 필요하게 됐다.

열심히 검색하고, try and error를 통해 @Validated 을 사용하도록 설정하였다.


pom.xml

<!-- Hibernate Validator -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>4.2.0.Final</version>
		</dependency>


dispatcherServlet.xml

<mvc:annotation-driven /≷

  <bean id="webBindingInitializer"
		class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
		<!-- validator -->
		<property name="validator" ref="validator" />
	</bean>
	
  <!-- validator -->
	<bean id="validator"
		class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
	<bean
		class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor" />


model class

model class 에 annotation을로 validation rule을 정하자.

JSR-303 스펙을 따른다.

public class Store {
	@Length(max = 32)
	private String aa;
	@Length(max = 10)
	@NotEmpty
	private String bb;

	public String getAa() {
		return aa;
	}

	public void setAa(String aa) {
		this.aa = aa;
	}

	public String getBb() {
		return bb;
	}

	public void setBb(String bb) {
		this.bb = bb;
	}

}


controller

	public String validStore(ModelMap model, @Validated Store store) {
		
		return ICommonConstants.TO_JSON;
	}


적절하지 않은 값에 대해서는 BindException을 던진다.

이쁘게 결과 메세지를 다듬었다.


	BindingResult bindingResult = ((BindException) th).getBindingResult();
	FieldError fieldError = bindingResult.getFieldError();
	String resultMessage = "[" + fieldError.getField() + "] : "	
                                              + fieldError.getDefaultMessage();


자세한 건 참고한 블로그를 보자.

ref:

http://sway.tistory.com/722

http://dev.anyframejava.org/docs/anyframe/plugin/foundation/4.6.1/reference/html/ch13.html

http://linuxism.tistory.com/653

http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s07.html

Posted by 뚜벅이조
,

dispatcher-Servlet.xml 설정. 또는 applicationContext.xml

* <context:component-scan ...> 바로 뒤에 <ehcache:annotation-driven ..> 와야 한다고 한다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.2.xsd">

  <context:annotation-config />

  <context:component-scan base-package="com.samsung.mcm.master" />
  <!-- Ehcache -->
  <ehcache:annotation-driven cache-manager="cacheManager" />
  <ehcache:config cache-manager="cacheManager">
    <ehcache:evict-expired-elements
      interval="60" />
  </ehcache:config>

  <bean id="cacheManager"
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:ehcache.xml"></property>
  </bean>
  
  ...

ehcache.xml 설정

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
  <defaultCache eternal="false" maxElementsInMemory="100"
    overflowToDisk="false" />
  <cache name="countCache"
    maxElementsInMemory="10"
    eternal="false"
    overflowToDisk="false"
    diskPersistent="false"
    timeToIdleSeconds="0" 
    timeToLiveSeconds="60"
    memoryStoreEvictionPolicy="LRU" />
    
</ehcache>

annotation 설정

@Cacheable(cacheName = "countCache")
 public List<TestObject> getCount() {
    return testMapper.selectCount();
  }

ref: 

http://ehcache.org

http://javacan.tistory.com/123

http://shonm.tistory.com/m/post/view/id/437


Posted by 뚜벅이조
,

Tomcat6에서 Spring 3 의 MultipartFile 처리시 Servlet 버전의 차이로 인해 이슈가 발생할 수 있다.

 

[원인]

문제의 발단을 이렇습니다.

chrome의 RestConsole app을 이용하여 file upload를 테스트 하려는데

다음과 같은 error 가 발생했습니다.

[2012.07.11 09:38:50.251][DEBUG][o.s.w.m.support.MultipartFilter] Resolving multipart request [/master/api/v1/device-platforms/6698/images/ICON] with MultipartFilter
7월 11, 2012 9:38:50 오전 org.apache.catalina.core.StandardWrapperValve invoke
심각: Servlet.service() for servlet dispatcher threw exception
java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getParts()Ljava/util/Collection;
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:57)
at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:58)
at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:110)

MultipartFilter에서 file을 처리하다가 HttpServletRequest의 getParts() 메소드를 호출하는데

그런 메소드는 없다는 거죠.. 

[결론]

web.xml 에 다음과 같은 설정이 있습니다.

<filter>
    <filter-name>multipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter
    </filter-class>
    <init-param>
	<param-name>multipartResolverBeanName</param-name>
	<param-value>multipartResolver</param-value>
    </init-param>
</filter>

<filter-mapping>
	<filter-name>multipartFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

MultipartFilter를 사용하겠다는 것이고요.

이 클래스는 default로 filterMultipartResolver bean을 찾는데

대신 multipartResolver를 찾아라 라는 설정입니다.

 

빈 등록은 다음과 같습니다.

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- one of the properties available; the maximum file size in bytes -->
    <property name="maxUploadSize" value="1000000000" />    
</bean>

근데 에러메세지를 보면 CommonsMultipartResolver가 아닌 StandardServletMultipartResolver를 쓰고 있네요.

 

API를 보면 다음과 같은 내용이 있습니다.

Looks up the MultipartResolver on each request, to avoid initialization order issues (when using ContextLoaderServlet, the root application context will get initialized after this filter).

 

ContextLoaderServlet은 ContextLoaderListener의 예전 버전이라 할수 있죠.

프로젝트에서는 classpath:dispatcherServlet.xml 하나로 설정을 다 하고 있어서.

ContextLoaderListener를 쓰지 않았습니다.

 

다음을 추가 했습니다.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:dispatcherServlet.xml     
    </param-value>
  </context-param>
  <listener>
    <display-name>ContextLoader</display-name>
    <listener-class>org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>

 

삽질이 궁금하시다면 ~

[문제 해결 과정]

검색-

getParts() 메소드는 servlet-api 3.0 에서 지원되는 메소드네요.

pom.xml에 servlet-api 3.0 을 넣어줬습니다.

같은 에러~

tomcat 라이브러리를 쓰니까 연결이 안되는 것인가?

검색-

tomcat6는 servlet-api 2.5            , tomcat7는 servlet-api 3.0

spring 3.0.7은 servlet-api 2.5 기반  , spring 3.1.1은 tomcat7 기반

어라? 3.1.1은 tomcat7기반인데 왜 tomcat6를 쓰지?

이슈제기-

store 에서는 잘 되고 있다는 박병주 책임님의 제보-

어떻게??

Spring doc 분석 -

StandardServletMultipartResolver 는 servlet 3 를 사용한다.

CommonsMultipartResolver 를 bean으로 등록했다

MultipartFilter 는 왜 CommonsMultipartResolver를 찾지 못하는가?

 

api 분석 -

아하!! ContextLoader가 필요하구나

 

ref

http://mvnrepository.com/artifact/org.springframework/spring-webmvc/3.1.1.RELEASE

http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/multipart/support/MultipartFilter.html

http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-multipart-resolver-commons

 


'framework&tools > spring' 카테고리의 다른 글

Spring Controller에 Validator 적용하기  (0) 2013.03.08
spring + ehcache 사용  (0) 2012.10.31
spring mvc annotation으로만 구현해보기  (0) 2012.04.04
Posted by 뚜벅이조
,
xml에서 bean을 관리하지 않고 class에서 annotation을 사용해서 controller, service, dao bean을 바로 등록할수있다.

applicationCotext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc
             http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
                                     http://www.springframework.org/schema/beans 
                                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                     http://www.springframework.org/schema/context 
                                    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">

    <context:component-scan base-package="com.sec.ams"/>

    <context:annotation-config/>

    <mvc:annotation-driven/>


bean annotation
@Service :service 
@Controller :controller
@Repository :dao

method annotation
@PostConstruct : bean 등록시 호출할 init 메소드



예제

TestService.java
@Service
public class TestService{
    @Autowired
    private TestDao testDao;
    
    public void testMethod(){
        testDao.test();
    }
}

TestContoller.java

@Controller
@RequestMapping("test")

public class TestController{

    @AutoWired
    private TestService testService;

    @RequestMapping("test1")
    public String test(){

        testService.testMothod();

    }

}

TestDao.java

@Repository
public class TestDao{

    @PostConstruct
    public void init(){

    ....
    }

    public void test(){

    ...

    }

}


'framework&tools > spring' 카테고리의 다른 글

Spring Controller에 Validator 적용하기  (0) 2013.03.08
spring + ehcache 사용  (0) 2012.10.31
Tomcat6에서 Spring 3 의 MultipartFile 처리  (0) 2012.07.11
Posted by 뚜벅이조
,