오류 메세지 : 

Invalid property 'metaDatas[256]' of bean class[com.comas.solme.ecm.admin.cm.action.ContentsModel]: Index of out of bounds in property path 'metaDatas[256]'; nested exception is java.lang.IndexOutOfBoundsException: Index: 256, Size: 256
DefaultController.java
@Controller
public class DefaultController {
    public static class Command {
        private List<MetaValueModel> metaDatas = new ArrayList<MetaValueModel>();
        // ...
    }
 
    public void edit(@ModelAttribute Commmand commmand) {
        // ...
    }
 
 
}

 

위와 같은 오류는 스프링 MVC 에서 폼 Path 에 해당하는 속성의 컬렉션 크기를 256으로 설정되어 있기 때문에 발생한다. 엄밀히 말하면 오류라기보다는 설정상의 문제.

다음과 같이 컬렉션의 제한 크기를 늘려주면 된다.  주의할 점은 반드시WebDataBinder 설정시 가장 먼저 setAutoGrowNestedPaths 값을 true 로 바꿔주고 초기화를 진행해야한다는 것이다. 안 그럼 "DataBinder is already initialized - call setAutoGrowNestedPaths before other configuration methods" 이런 오류를 만날 것이다.

  • binder.setAutoGrowNestedPaths(true);
  • binder.setAutoGrowCollectionLimit(5000);

 

DefaultController.java
@Controller
public class DefaultController {
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setAutoGrowNestedPaths(true); // insert this line
        binder.setAutoGrowCollectionLimit(5000); // insert thist line
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        binder.registerCustomEditor(Date.classnew CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(String.classnew StringTrimmerEditor(true));
    }
}


maven 의 assmbly 기능을 이용해서 단일 dependency 로 만들었을 경우(jar-with-dependencies 사용)에 만들어진 jar 파일로 실행하면 spring.scheas 파일들이 중복되는 오류가 발생한다.

해당 이슈에 대하여서 Spring JIRA 에 등록되어 있다. http://jira.codehaus.org/browse/MASSEMBLY-360

여하튼, 해결 방법은 assembly:assembly 를 시행할 프로젝트의 리소스 폴더에 META-INF 하위로 스프링 스키마 파일들을 복사해놓고 assembly 시키는 것이다.

예를 들어
디렉터리 구조
src/main/resources/META-INF/spring.handlers
src/main/resources/META-INF/spring.schemas

console>mvn assembly:assembly

하면 된다. 스키마 파일들은 스프링 jar 파일들을 풀면 구할 수 있다.
Filter 안에서 스프링을 사용하기 위해선 스프링에서 제공하는 DelegatingFilterProxy 를 이용한다. 스프링 필터 체인방식은 예전에 Acegi 에서 사용된 시큐리티 필터 체인으로부터 가져온것으로 현재는 Spring-Securtity 프로젝트로 통합되었다.

여하튼, 사용하는 방법은 javax.servlet.Filter 인터페이스를 상속받은
DelegatingFilterProxy 필터 체인 클래스를 사용하면 된다.

1.
GenericFilterBean 클래스 상속받은 Filter 클래스 작성


package com.vine.edms.web;

 

import java.io.IOException;

 

import javax.servlet.FilterChain;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

import org.springframework.web.filter.GenericFilterBean;

 

import com.vine.edms.webapp.envirement.WebAppEnvirementService;

import com.vine.util.CommonWebFilter;

 

public class VineWebFilter extends GenericFilterBean {

       private WebAppEnvirementService envirement; // Spring beans

       public void setWebAppEnvirementService(WebAppEnvirementService envirement) {

             this.envirement = envirement;

       }

 

       public void doFilter(ServletRequest request, ServletResponse response,   FilterChain chain) throws IOException, ServletException {

             CommonWebFilter.addCommonAttributes(request);

             request.setAttribute("_VW_SKIN", envirement.getSkin());

             request.setAttribute("_VW_TITLE", envirement.getAppTitle());

             chain.doFilter (request, response);

       }

}


2. Spring bean 설정

<bean id="edmsWebAppCommonFilter" class="com.vine.edms.web.VineWebFilter" p:webAppEnvirementService-ref="edmsWebAppEnvirementService" />



3. web.xml 등록

가장 중요한 web.xml 설정 부분이다. init-param 속성을 이용하여 별도의 bean 을 설정하지도 않지만, 기본적으로 filter-name 과 동일한 bean 을 사용하여 필터를 매핑한다.

여기선 edmsWebAppCommonFilter 명을 가진 빈을 만들었고, web.xml 에서 또한 필터 이름을 edmsWebAppCommonFilter 로 정의하였다.


그리고 필터 체인은 2개 이상을 사용해도 무방하다. 아래 샘플은 스프링 시큐티리 체인 필터 또한 같이 사용하는 것을 알 수 있다.

    

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

      

<filter>

<filter-name>edmsWebAppCommonFilter</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

 

  

<filter-mapping>

<filter-name>edmsWebAppCommonFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>



요즘 스프링 시큐리티에 좀더 깊이있는 정보가 필요하다. 레퍼런스 또한 부족하기 그지 없으니.. 어디 좋은 책이라도 없으려나ㅡㅜ
  1. BlogIcon Michael Kors outlet 2013.07.10 16:04

    당신은 내가사랑할 만한 사람이 아니예요,사랑하지 않으면 안될 사람이예요.

그냥 레퍼런스 보거나 스프링책 좀 정상적(?)으로 읽으면 알만한 사실이다만,
많은 사람들이 스프링으로 작성된 소스에 대해서 접근하는 것을 꺼려한다.

jsp 에서 로직을 처리하길 원하진 않지만, 급한 상황 및 테스트용도라면 로직을 뽑아내서 처리할 일도 필요할 듯하다.
물론 처리 했다면 삭제해서 정리해주는 말끔한 매너를 보여주어야지만.

1. jsp 또는 서블릿으로부터 Spring Appliation Context 를 조회한다. jsp 나 서블릿은 WebApplicationContext 를 얻을 수 있다. Web Application 이 아닌 소스에서는 XmlApplicationContext 를 이용한다.

2. 얻어온 Applicatoin Context 로부터 스프링빈을 가져온다.

아래에 샘플이 있다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"

  import="org.springframework.web.context.WebApplicationContext"

  import="org.springframework.web.context.support.WebApplicationContextUtils"

  import="com.comas.common.mail.MailInfo"

  import="com.comas.common.mail.MailService"     

%>

<%

 

ServletContext servletContext = this.getServletContext();

WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);


// custom codes

MailService mailService = (MailService)wac.getBean("mailService");

MailInfo from = new MailInfo("edms@canon-bs.co.kr", "EDMS");

MailInfo to = new MailInfo("slothink@gmail.com", "pyun");

 

mailService.send("subject", "<html><head><title>title</title></head><body>it is content</body></html>", from, to);

 

%>


자 어렵다고 불평하지 말자. 끝.

+ Recent posts