복붙노트

[SPRING] Spring + Web MVC : dispatcher-servlet.xml과 applicationContext.xml (공유 보안 포함)

SPRING

Spring + Web MVC : dispatcher-servlet.xml과 applicationContext.xml (공유 보안 포함)

두 컨텍스트, 즉 dispatcher-servlet.xml과 applicationContext.xml을 사용하는 올바른 방법은 무엇입니까? 어디로 간다?

서블릿 컨테이너에 배포 된 상당히 일반적인 앱을 작성하고 싶습니다. JSP보기가있는 컨트롤러가 있습니다. 백엔드에는 몇 가지 중요한 논리가 있습니다. 정말 두 문맥이 모두 필요합니까? 서로 어떻게 관련이 있습니까? 어떤 것을 넣을 지 어떻게 결정할 수 있습니까?

또한, 내 응용 프로그램에 Spring 보안을 사용하려고합니다. 필자는 웹 컨트롤러뿐만 아니라 더 깊은 계층에서의 기능 (예 : 주석이있는 선언적 보안)을 사용하고자 할 수 있습니다. 이 경우 작동하도록 보안을 어떻게 구성해야합니까? 그 파일 중 하나에 있어야합니까 (?), 또는 둘 다?

해결법

  1. ==============================

    1.dispatcher-servlet.xml 파일에는 Spring MVC에 대한 모든 구성이 포함되어 있습니다. 그래서 당신은 ViewHandlerResolvers, ConverterFactories, Interceptors 등과 같은 빈을 발견 할 것입니다. 이 빈은 모두 Spring MVC의 일부이며, 웹 MVC는 웹 요청 처리 방법을 구조화하고 데이터 바인딩,보기 해상도 및 요청 매핑과 같은 유용한 기능을 제공하는 프레임 워크입니다.

    dispatcher-servlet.xml 파일에는 Spring MVC에 대한 모든 구성이 포함되어 있습니다. 그래서 당신은 ViewHandlerResolvers, ConverterFactories, Interceptors 등과 같은 빈을 발견 할 것입니다. 이 빈은 모두 Spring MVC의 일부이며, 웹 MVC는 웹 요청 처리 방법을 구조화하고 데이터 바인딩,보기 해상도 및 요청 매핑과 같은 유용한 기능을 제공하는 프레임 워크입니다.

    Spring MVC 나 다른 프레임 워크를 사용할 때 application-context.xml을 선택적으로 포함 할 수 있습니다. 이렇게하면 데이터 지속성과 같은 것을 지원하는 다른 유형의 스프링 빈을 구성하는 데 사용할 수있는 컨테이너가 제공됩니다. 기본적으로,이 설정 파일은 Spring이 제공하는 다른 모든 장점들을 가져 오는 곳입니다.

    이 구성 파일은 다음과 같이 web.xml 파일에 구성됩니다.

    디스패처 구성

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/spring/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    응용 프로그램 구성

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/application-context.xml</param-value>
    </context-param>
    
    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    

    컨트롤러를 구성하려면 @Controller로 주석을 달고 dispatcher-context.xml 파일에 다음을 포함시킵니다.

    <mvc:annotation-driven/>
    <context:component-scan base-package="package.with.controllers.**" />
    
  2. ==============================

    2.Kevin의 대답에 덧붙이 자면, 실제로 거의 모든 사소한 Spring MVC 응용 프로그램에는 응용 프로그램 컨텍스트 (스프링 MVC 디스패처 서블릿 컨텍스트에만 해당)가 필요하다는 것을 알게되었습니다. 애플리케이션 컨텍스트에서 다음과 같은 웹 이외의 모든 문제를 구성해야합니다.

    Kevin의 대답에 덧붙이 자면, 실제로 거의 모든 사소한 Spring MVC 응용 프로그램에는 응용 프로그램 컨텍스트 (스프링 MVC 디스패처 서블릿 컨텍스트에만 해당)가 필요하다는 것을 알게되었습니다. 애플리케이션 컨텍스트에서 다음과 같은 웹 이외의 모든 문제를 구성해야합니다.

    좀 더 구체적으로 설명하기 위해, Spring MVC 애플리케이션 (Spring 4.1.2)을 최신 버전으로 설정할 때 사용한 Spring 구성의 예가 있습니다. 개인적으로, 나는 여전히 WEB-INF / web.xml 파일을 사용하는 것을 선호하지만 이는 실제로 xml 구성에 불과합니다.

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
    
      <filter>
        <filter-name>openEntityManagerInViewFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
      </filter>
    
      <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
      </filter>
    
      <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    
      <filter-mapping>
        <filter-name>openEntityManagerInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    
      <servlet>
        <servlet-name>springMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
          <param-name>contextClass</param-name>
          <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>com.company.config.WebConfig</param-value>
        </init-param>
      </servlet>
    
      <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
      </context-param>
    
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.company.config.AppConfig</param-value>
      </context-param>
    
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    
      <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    
      <session-config>
        <session-timeout>30</session-timeout>
      </session-config>
    
      <jsp-config>
        <jsp-property-group>
          <url-pattern>*.jsp</url-pattern>
          <scripting-invalid>true</scripting-invalid>
        </jsp-property-group>
      </jsp-config>
    
    </web-app>
    

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = "com.company.controller")
    public class WebConfig {
    
      @Bean
      public InternalResourceViewResolver getInternalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
      }
    }
    

    @Configuration
    @ComponentScan(basePackages = "com.company")
    @Import(value = {SecurityConfig.class, PersistenceConfig.class, ScheduleConfig.class})
    public class AppConfig {
      // application domain @Beans here...
    }
    

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
      @Autowired
      private LdapUserDetailsMapper ldapUserDetailsMapper;
    
      @Override
        protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/").permitAll()
          .antMatchers("/**/js/**").permitAll()
          .antMatchers("/**/images/**").permitAll()
          .antMatchers("/**").access("hasRole('ROLE_ADMIN')")
          .and().formLogin();
    
        http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
        }
    
      @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth.ldapAuthentication()
          .userSearchBase("OU=App Users")
          .userSearchFilter("sAMAccountName={0}")
          .groupSearchBase("OU=Development")
          .groupSearchFilter("member={0}")
          .userDetailsContextMapper(ldapUserDetailsMapper)
          .contextSource(getLdapContextSource());
        }
    
      private LdapContextSource getLdapContextSource() {
        LdapContextSource cs = new LdapContextSource();
        cs.setUrl("ldaps://ldapServer:636");
        cs.setBase("DC=COMPANY,DC=COM");
        cs.setUserDn("CN=administrator,CN=Users,DC=COMPANY,DC=COM");
        cs.setPassword("password");
        cs.afterPropertiesSet();
        return cs;
      }
    }
    

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(transactionManagerRef = "getTransactionManager", entityManagerFactoryRef = "getEntityManagerFactory", basePackages = "com.company")
    public class PersistenceConfig {
    
      @Bean
      public LocalContainerEntityManagerFactoryBean getEntityManagerFactory(DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource);
        lef.setJpaVendorAdapter(getHibernateJpaVendorAdapter());
        lef.setPackagesToScan("com.company");
        return lef;
      }
    
      private HibernateJpaVendorAdapter getHibernateJpaVendorAdapter() {
        HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
        hibernateJpaVendorAdapter.setDatabase(Database.ORACLE);
        hibernateJpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.Oracle10gDialect");
        hibernateJpaVendorAdapter.setShowSql(false);
        hibernateJpaVendorAdapter.setGenerateDdl(false);
        return hibernateJpaVendorAdapter;
      }
    
      @Bean
      public JndiObjectFactoryBean getDataSource() {
        JndiObjectFactoryBean jndiFactoryBean = new JndiObjectFactoryBean();
        jndiFactoryBean.setJndiName("java:comp/env/jdbc/AppDS");
        return jndiFactoryBean;
      }
    
      @Bean
      public JpaTransactionManager getTransactionManager(DataSource dataSource) {
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(getEntityManagerFactory(dataSource).getObject());
        jpaTransactionManager.setDataSource(dataSource);
        return jpaTransactionManager;
      }
    }
    

    @Configuration
    @EnableScheduling
    public class ScheduleConfig {
      @Autowired
      private EmployeeSynchronizer employeeSynchronizer;
    
      // cron pattern: sec, min, hr, day-of-month, month, day-of-week, year (optional)
      @Scheduled(cron="0 0 0 * * *")
      public void employeeSync() {
        employeeSynchronizer.syncEmployees();
      }
    }
    

    보시다시피, 웹 구성은 전반적인 스프링 웹 응용 프로그램 구성의 일부일뿐입니다. 필자가 작업 한 대부분의 웹 애플리케이션은 web.xml의 org.springframework.web.context.ContextLoaderListener를 통해 부트 스트래핑 된 본격적인 애플리케이션 컨텍스트를 필요로하는 디스패처 서블릿 구성 외부에있는 많은 관심사를 가지고 있습니다.

  3. ==============================

    3.

    <?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:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:cache="http://www.springframework.org/schema/cache"
        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://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  http://www.springframework.org/schema/cache 
            http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    
            <mvc:annotation-driven/>
            <context:component-scan base-package="com.testpoc.controller"/>
    
            <bean id="ViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="ViewClass" value="org.springframework.web.servlet.view.JstlView"></property>
                <property name="prefix">
                    <value>/WEB-INF/pages/</value>
                </property>
                <property name="suffix">
                    <value>.jsp</value>
                </property>
            </bean>
    
    </beans>
    
  4. ==============================

    4.

    <mvc:annotation-driven />
    <mvc:default-servlet-handler />
    <mvc:resources mapping="/resources/**" location="/resources/" />
    
    <context:component-scan base-package="com.tridenthyundai.ains" />
    
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
    
    <bean id="messageSource" 
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="/WEB-INF/messages" />
    </bean>
    
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
    

  5. ==============================

    5.

    <?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:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        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://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd ">
    
        <mvc:annotation-driven />
        <mvc:default-servlet-handler />
        <mvc:resources mapping="/resources/**" location="/resources/" />
    
        <context:component-scan base-package="com.sapta.hr" />
    
        <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
    
        <bean id="messageSource" 
            class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
            <property name="basename" value="/WEB-INF/messages" />
        </bean>
    
        <bean id="viewResolver"
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    
            <property name="prefix">
                <value>/WEB-INF/pages/</value>
            </property>
            <property name="suffix">
                <value>.jsp</value>
            </property>
        </bean>
    
    </beans>
    
  6. ==============================

    6.

    <?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_3_0.xsd" id="WebApp_ID" version="3.0">
      <display-name>TestPOC</display-name>
    
      <servlet>
            <servlet-name>mvc-dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>mvc-dispatcher</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
        </context-param>
    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    
  7. from https://stackoverflow.com/questions/16458754/spring-web-mvc-dispatcher-servlet-xml-vs-applicationcontext-xml-plus-shared by cc-by-sa and MIT license