Struts 整合 SpringMVC 過程:這篇文章是我在整合過程當中所作的記錄和筆記java
原機制是攔截了全部 url ,即 <url-pattern>/*</url-pattern>web
新機制爲了將 structs2 的 url 與 SpringMVC 的 url 區分開來,則修改了攔截屬性spring
<!-- 原代碼 --> <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>
<!-- 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類:【兩個配置的區別】sql
AppConfig.java數據庫
@Configuration @Import({KmAppConfig.class}) public class AppConfig { }
MvcConfig.java服務器
@Configuration @Import({KmMvcConfig.class}) public class MvcConfig { }
基於Config類,配置具體的應用Configsession
KmAppConfig.javaapp
@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(); } }
AbstractBaseControllerdom
/** * 抽象的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()); } }