Struts 整合 SpringMVC 过程:这篇文章是我在整合过程中所做的记录和笔记

web.xml :筛选器机制过滤

  • 原机制是拦截了所有 url ,即 <url-pattern>/*</url-pattern>

  • 新机制为了将 structs2 的 url 与 SpringMVC 的 url 区分开来,则修改了拦截属性

<!-- 原代码 -->
   <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>  
        <dispatcher>FORWARD</dispatcher> 
    </filter-mapping>
    
    
<!-- 新代码 -->
   <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
        <dispatcher>REQUEST</dispatcher> 
        <dispatcher>FORWARD</dispatcher> 
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.jsp</url-pattern>
        <dispatcher>REQUEST</dispatcher>  
        <dispatcher>FORWARD</dispatcher> 
    </filter-mapping>

web.xml struts 整合 SpringMVC

<!-- SpringMVC 配置开始 -->
     <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
        instead of the default XmlWebApplicationContext -->
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>
    <!-- Configuration locations must consist of one or more comma- or space-delimited
        fully-qualified @Configuration classes. Fully-qualified packages may also be
        specified for component-scanning -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>spring.config.AppConfig</param-value>
    </context-param>
    <!-- Bootstrap the root application context as usual using ContextLoaderListener -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- Declare a Spring MVC DispatcherServlet as usual -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
            instead of the default XmlWebApplicationContext -->
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>
                org.springframework.web.context.support.AnnotationConfigWebApplicationContext
            </param-value>
        </init-param>
        <!-- Again, config locations must consist of one or more comma- or space-delimited
            and fully-qualified @Configuration classes -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>spring.config.MvcConfig</param-value>
        </init-param>
    </servlet>
    <!-- map all requests for /km/* to the dispatcher servlet -->
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/km/*</url-pattern>
    </servlet-mapping>
    <!-- SpringMVC 配置结束 -->
  • 基于web.xml配置文件的配置属性,需要配置两个Config类:【两个配置的区别】

    • AppConfig.java

    @Configuration
    @Import({KmAppConfig.class})
    public class AppConfig {
    
    }
    • MvcConfig.java

    @Configuration
    @Import({KmMvcConfig.class})
    public class MvcConfig {
    
    }
  • 基于Config类,配置具体的应用Config

    • KmAppConfig.java

    @Configuration
    @ComponentScan(basePackages = "com.teemlink.km.") //扫描包体
    public class KmAppConfig implements TransactionManagementConfigurer,ApplicationContextAware {
    private static ApplicationContext applicationContext;
    
    @Autowired
    private DataSource dataSource;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        KmAppConfig.applicationContext = applicationContext;
    }
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    
    @Bean
    public DataSource dataSource() {
        //如何读取配置资源的数据?
        String url = "jdbc:jtds:sqlserver://192.168.80.47:1433/nj_km_dev";
        String username = "sa";
        String password = "teemlink";
        DriverManagerDataSource ds = new DriverManagerDataSource(url, username, password);
        ds.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");
        return ds;
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
        
    }
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }
    }
    • KmMvcConfig.java

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = "com.teemlink.km.**.controller")
    public class KmMvcConfig extends WebMvcConfigurerAdapter {
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    }

基于SpringMVC 的 Controller - Service - Dao 框架

  • AbstractBaseController

    /**
     * 抽象的RESTful控制器基类
     * @author Happy
     *
     */
    @RestController
    public abstract class AbstractBaseController {
        
        @Autowired  
        protected HttpServletRequest request;
        
        @Autowired
        protected HttpSession session;
        
        protected Resource success(String errmsg, Object data) {
            return new Resource(0, errmsg, data, null);
        }
        
        protected Resource error(int errcode, String errmsg, Collection<Object> errors) {
            return new Resource(errcode, errmsg, null, errors);
        }
        private Resource resourceValue;
        public Resource getResourceValue() {
            return resourceValue;
        }
        public void setResourceValue(Resource resourceValue) {
            this.resourceValue = resourceValue;
        }
        
        /**
         * 资源未找到的异常,返回404的状态,且返回错误信息。
         * @param e
         * @return
         */
        @ExceptionHandler(RuntimeException.class)
        @ResponseStatus(HttpStatus.NOT_FOUND)
        public Resource resourceNotFound(RuntimeException e) {
            return error(404, "Not Found", null);
        }
        /**
         * 运行时异常,服务器错误,返回500状态,返回服务器错误信息。
         * @param e
         * @return
         */
        @ExceptionHandler(RuntimeException.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public Resource error(RuntimeException e) {
            return error(500, "Server Error", null);
        }
        
        /**
         * Restful 接口返回的资源对象
         * 
         */
        @JsonInclude(Include.NON_EMPTY)
        public class Resource implements Serializable {
            private static final long serialVersionUID = 2315158311944949185L;
            private int errcode;
            private String errmsg;
            private Object data;
            private Collection<Object> errors;
            public Resource() {}
            
            public Resource(int errcode, String errmsg, Object data, Collection<Object> errors) {
                this.errcode = errcode;
                this.errmsg = errmsg;
                this.data = data;
                this.errors = errors;
            }
            public int getErrcode() {
                return errcode;
            }
            public void setErrcode(int errcode) {
                this.errcode = errcode;
            }
            public String getErrmsg() {
                return errmsg;
            }
            public void setErrmsg(String errmsg) {
                this.errmsg = errmsg;
            }
            public Object getData() {
                return data;
            }
            public void setData(Object data) {
                this.data = data;
            }
            public Collection<Object> getErrors() {
                return errors;
            }
            public void setErrors(Collection<Object> errors) {
                this.errors = errors;
            }
        }
    }
  • IService

    /**
     *
     * @param <E>
     */
    public interface IService<E> {
        
        /**
         * 创建实例
         * @param entity
         * @return
         * @throws Exception
         */
        public IEntity create(IEntity entity) throws Exception;
        
        /**
         * 更新实例
         * @param entity
         * @return
         * @throws Exception
         */
        public IEntity update(IEntity entity) throws Exception;
        
        /**
         * 根据主键获取实例
         * @param pk
         * @return
         * @throws Exception
         */
        public IEntity find(String pk) throws Exception;
        
        /**
         * 删除实例
         * @param pk
         * @throws Exception
         */
        public void delete(String pk) throws Exception;
        
        /**
         * 批量删除实例
         * @param pk
         * @throws Exception
         */
        public void delete(String[] pk) throws Exception;
        
    }
  • AbstractBaseService

    /**
     * 抽象的业务基类
     *
     */
    public abstract class AbstractBaseService {
        
        /**
         * @return the dao
         */
        public abstract IDAO getDao();  
    
        @Transactional
        public IEntity create(IEntity entity) throws Exception {
            if(StringUtils.isBlank(entity.getId())){
                entity.setId(UUID.randomUUID().toString());
            }
            return getDao().create(entity);
        }
        @Transactional
        public IEntity update(IEntity entity) throws Exception {
            return getDao().update(entity);
        }
        public IEntity find(String pk) throws Exception {
            return getDao().find(pk);
        }
        @Transactional
        public void delete(String pk) throws Exception {
            getDao().remove(pk);
        }
        @Transactional
        public void delete(String[] pks) throws Exception {
            for (int i = 0; i < pks.length; i++) {
                getDao().remove(pks[i]);
            }
        }
    }
  • IDAO

    /**
     *
     */
    public interface IDAO {
        
        public IEntity create(IEntity entity) throws Exception;
        public void remove(String pk) throws Exception;
        public IEntity update(IEntity entity) throws Exception;
        public IEntity find(String id) throws Exception;
        
    }
  • AbstractJdbcBaseDAO

    /**
     * 基于JDBC方式的DAO抽象实现,依赖Spring的JdbcTemplate和事务管理支持
     *
     */
    public abstract class AbstractJdbcBaseDAO {
        
        
        @Autowired
        public JdbcTemplate jdbcTemplate;
        
        protected String tableName;
        
        public JdbcTemplate getJdbcTemplate() {
            return jdbcTemplate;
        }
        public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
        /**
         * 构建分页sql
         * @param sql
         * @param page
         * @param lines
         * @param orderbyFile
         * @param orderbyMode
         * @return
         * @throws SQLException
         */
        protected abstract String buildLimitString(String sql, int page, int lines,
                String orderbyFile, String orderbyMode) throws SQLException ;
        
        
        /**
         * 获取数据库Schema
         * @return
         */
    //    protected abstract String getSchema();
        
        /**
         * 获取表名
         * @return
         */
        protected String getTableName(){
            return this.tableName;
        }
        
        /**
         * 获取完整表名
         * @return
         */
        public String getFullTableName() {
            return getTableName().toUpperCase();
        }
        
        
    }

测试框架

  • 基本测试框架

     /**
     * 单元测试基类,基于Spring提供bean组件的自动扫描装配和事务支持
     *
     */
    @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = KmAppConfig.class)
    @Transactional
    public class BaseJunit4SpringRunnerTest {
    
    }  
  • 具体实现:(以Disk为例)

    public class DiskServiceTest extends BaseJunit4SpringRunnerTest {
        
        @Autowired
        DiskService service;
        
        @Before
        public void setUp() throws Exception {
            
        }
        @After
        public void tearDown() throws Exception {
        }
        
        @Test
        public void testFind() throws Exception{
            Disk disk = (Disk) service.find("1");
            Assert.assertNotNull(disk);
        }
        
        @Test
        @Commit
        public void testCreate() throws Exception{
            Disk disk = new Disk();
            disk.setName("abc");
            disk.setType(1);
            disk.setOrderNo(0);
            disk.setOwnerId("123123");
            service.create(disk);
            Assert.assertNotNull(disk.getId());
        }
    }

Seven_Nee
614 声望53 粉丝