1.pom文件导入依赖,如果设置了<packing>war<packing>并想使用war包,那么在tomcat中的Deployment中请通过+选择External Source再选中这个war包;如果没有设置,那么请通过+选择Artifact再选择对应的“模块名+Web exploded”的,修改好Application Context后请通过“编辑”的一支笔一样的图标按钮,将右侧的jar文件放入左侧的lib目录下。
如果是war方式,请注意修改代码后及时clear和compile;如果选择的是tomcat热部署,请记得把jar文件放入lib文件夹下。配置图片放在本文最后
我个人比较喜欢测试代码时不打包,因为tomcat选择打包的war需要每次修改后重新clear和compile。而选择添加jar文件则可以热部署,修改后测试效果更快更省时间。
2.写一个类继承
AbstractAnnotationConfigDispatcherServletInitializer
/**
* 相当于配置了一个DispatcherServlet
* 如果是父子容器,就在getRootConfigClasses中写父容器,getServletConfigClasses中写子容器
* 但如果只有一个容器,就写在getRootConfigClasses中
* 这个类需要servlet的依赖
*/
public class WebMvcConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 添加真正的配置类,可以有多个,
* 例如WebSocketConfig需要实现两个接口,但是它们有相同的方法需要重写
* 那么可以在WebSocketConfig中写一个内部类A,再把内部类A也配置进去
* @return
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{WebSocketConfig.class};
// return new Class[]{WebSocketConfig.class, A.class};
}
/**
* 如果你配置了父子容器,那么这里也需要配置
* 我个人觉得父子容器没必要,从来不用
* 正常来讲就选择配置getRootConfigClasses方法就可以
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[0];
}
/**
* 一般都写“/”,如果有特殊需要也可以自己改
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
3.配置类:
/**
* 实现WebMvcConfigurer接口可以重写该接口中的一些较为好用的方法,比较方便
*/
// 声明该类是配置类
@Configuration
// 打开MVC的注解驱动
@EnableWebMvc
// mapper文件所扫描的dao包
@MapperScan("com.nf.supermarket.dao")
// 组件扫描,主要是controller和service的实现类所在的包
@ComponentScan({"com.nf.supermarket.controller", "com.nf.supermarket.service.impl", "com.nf.supermarket.util", "com.nf.supermarket.aop"})
// 数据库连接所需数据文件获取
@PropertySource("classpath:sql/db.properties")
// 打开事务管理
@EnableTransactionManagement
// 切面代理
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class xxxConfig implements WebMvcConfigurer {
@Value("${mysql.url}")
private String url;
@Value("${mysql.username}")
private String username;
@Value("${mysql.password}")
private String password;
/**
* 配置druid的连接池
* 本来是需要同一个连接的,但连接池内部有其实现方法,只需要保证是同一个连接池即可
* 如果存在driverClassName,就可以根据url找到driverClassName,因此无需再配置
*
* @return 一个被spring管理的连接池
*/
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
/**
* 生成dao的代理类
*
* @return 返回一个被spring管理的sqlSessionFactory
* @throws Exception mapper文件未找到及getObject方法调用出错
*/
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
// 设置哪里找到mapper文件
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/**/*.xml"));
// 设置配置
sqlSessionFactoryBean.setConfiguration(configuration());
// 设置插件
sqlSessionFactoryBean.setPlugins(pageInterceptor());
return sqlSessionFactoryBean.getObject();
}
/**
* 注入事务驱动
*
* @return 数据源事务管理
*/
@Bean
public DataSourceTransactionManager dataSourceTransactionManager() {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource());
return dataSourceTransactionManager;
}
/**
* mybatis的配置
*
* @return SqlSessionFactoryBean对象所需设置的配置
*/
private org.apache.ibatis.session.Configuration configuration() {
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
// 输出执行的sql语句,日志某些类似的效果,更清晰了解做了什么
configuration.setLogImpl(StdOutImpl.class);
// 下划线转驼峰形式
configuration.setMapUnderscoreToCamelCase(true);
return configuration;
}
/**
* 分页插件,但项目中用了layui,因此只是借用了它的组合分页SQL语句功能
*
* @return 一个分页拦截器对象
*/
private PageInterceptor pageInterceptor() {
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
// 支持方法参数
properties.setProperty("supportMethodsArguments", "true");
// 参数合理化,使页数正确
properties.setProperty("reasonable", "true");
pageInterceptor.setProperties(properties);
return pageInterceptor;
}
/**
* 凡是/static路径开头的文件,一律到resouces文件下的static包下找
*
* @param registry 登记资源解析器
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
ResourceHandlerRegistration resourceHandlerRegistration = registry.addResourceHandler("/static/**");
resourceHandlerRegistration.addResourceLocations("classpath:/static/");
}
/**
* 视图解析
*
* @param registry 登记视图解析
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// WEB-INF前加/表示相对路径,如果不加在某些情况下会出错
registry.jsp("/WEB-INF/views/", ".jsp");
}
/**
* 添加拦截器,保证权限能够正常启用
*
* @param registry 登记拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptorRegistration = registry.addInterceptor(new UserInterceptor());
interceptorRegistration.addPathPatterns("/**");
interceptorRegistration.excludePathPatterns("/login");
// "/"是LoginController的默认,即启动时的界面
interceptorRegistration.excludePathPatterns("/");
interceptorRegistration.excludePathPatterns("/retrievePassword");
interceptorRegistration.excludePathPatterns("/getVerificationCode");
interceptorRegistration.excludePathPatterns("/updatePassword");
// static后面要加/**
interceptorRegistration.excludePathPatterns("/static/**");
InterceptorRegistration interceptorRegistration1 = registry.addInterceptor(new PowerInterceptor());
interceptorRegistration1.addPathPatterns("/unit/**");
interceptorRegistration1.addPathPatterns("/wholesaler/**");
interceptorRegistration1.addPathPatterns("/employee/**");
interceptorRegistration1.addPathPatterns("/userInfo/**");
interceptorRegistration1.addPathPatterns("/commodity/**");
}
/**
* 配合apache的commons依赖上传文件
*
* @return 文件上传处理
*/
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
commonsMultipartResolver.setMaxUploadSize(1024 * 1024 * 1024L);
return commonsMultipartResolver;
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(sdf);
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
//通过设置索引,让自己的转换器放在最前面,否则默认的jackson转换器会在前面,用不上我们设置的转换器.
converters.add(0, converter);
}
}
其实也就是实现
WebMvcConfigurer
里面可以重写一些有用的方法,根据需要来写,例如:我需要能够直接在浏览器地址访问web目录下和WEB-INF同级的html页面
@Configuration
@EnableWebSocketMessageBroker
@EnableWebMvc
@ComponentScan("com.test")
public class StompConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("chat");
registry.addEndpoint("chat").withSockJS();
}
/**
* 因为不能同时实现WebSocketMessageBrokerConfigurer和WebMvcConfigurer
* 所以写一个内部类分别实现
*/
class SssConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
ResourceHandlerRegistration resourceHandlerRegistration = registry.addResourceHandler("/*.html");
resourceHandlerRegistration.addResourceLocations("/");
ResourceHandlerRegistration resourceHandlerRegistration1 = registry.addResourceHandler("/*.js");
resourceHandlerRegistration1.addResourceLocations("/");
}
}
}
4.直接启动tomcat就可以了
tomcat配置图片: