持续学习&持续更新中…
守破离
【Java从零到架构师第③季】【36】SSM纯注解整合
纯注解—基本实现
Initializer取代web.xml
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVCConfiguration.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
SpringConfiguration(父容器)
main.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test_mybatis?useSSL=false
jdbc.username=root
jdbc.password=root
mybatis.typeAliasesPackage=programmer.lp.domain
mybatis.mapperScanPackage=programmer.lp.dao
mybatis.configLocation=mybatis-config.xml
SpringConfiguration:
@PropertySource("classpath:main.properties")
@MapperScan("${mybatis.mapperScanPackage}")
@ComponentScan("programmer.lp.service")
@EnableTransactionManagement
public class SpringConfiguration {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${mybatis.typeAliasesPackage}")
private String typeAliasesPackage;
@Value("${mybatis.configLocation}")
private String configLocation;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
Resource location = new ClassPathResource(configLocation);
sqlSessionFactoryBean.setConfigLocation(location);
return sqlSessionFactoryBean;
}
@Bean
public TransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager manager = new DataSourceTransactionManager();
manager.setDataSource(dataSource);
return manager;
}
}
SpringConfiguration(子容器)
@ComponentScan("programmer.lp.controller")
@EnableWebMvc
public class SpringMVCConfiguration {
}
controller、service、dao代码
dao:
public interface SkillDao {
@Insert("INSERT INTO skill(name, level) VALUES(#{name}, #{level})")
@SelectKey(statement = "SELECT LAST_INSERT_ID()",
keyProperty = "id",
keyColumn = "id",
before = false,
resultType = Integer.class)
boolean insert(Skill skill);
@Delete(("DELETE FROM skill WHERE id = #{id}"))
boolean delete(Integer id);
@Update("UPDATE skill SET name = #{name}, level = #{level} WHERE id = #{id}")
boolean update(Skill skill);
@Select("SELECT id, created_time, name, level FROM skill WHERE id = #{id}")
Skill get(Integer id);
@Select("SELECT id, created_time, name, level FROM skill")
List<Skill> list();
}
service:
@Service
@Transactional
public class SkillServiceImpl implements SkillService {
@Autowired
private SkillDao dao;
@Override
public boolean remove(Integer id) {
return dao.delete(id);
}
@Override
public boolean save(Skill skill) {
final Integer skillId = skill.getId();
if (skillId == null || skillId < 1) {
boolean result = dao.insert(skill);
System.out.println(skill.getId());
return result;
}
return dao.update(skill);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public Skill get(Integer id) {
return dao.get(id);
}
@Transactional(readOnly = true)
@Override
public List<Skill> list() {
return dao.list();
}
}
controller:
@Controller
@RequestMapping("/skill")
public class SkillController {
@Autowired
private SkillService service;
@PostMapping("/remove")
@ResponseBody
public String remove(Integer id) {
return service.remove(id) ? "删除成功" : "删除失败";
}
@PostMapping("/save")
@ResponseBody
public String save(Skill skill) {
return service.save(skill) ? "保存成功" : "保存失败";
}
@GetMapping("/get")
@ResponseBody
public Skill get(Integer id) {
return service.get(id);
}
@GetMapping("/list")
@ResponseBody
public List<Skill> list() {
return service.list();
}
}
纯注解—配置静态资源
@ComponentScan("programmer.lp.controller")
@EnableWebMvc
public class SpringMVCConfiguration implements WebMvcConfigurer {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
纯注解—配置拦截器
拦截器:
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
XML配置:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/assets/**"/>
<bean class="programmer.lp.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
注解配置:
方式一:
@ComponentScan("programmer.lp.controller")
@EnableWebMvc
public class SpringMVCConfiguration implements WebMvcConfigurer {
@Bean
public HandlerInterceptor myInterceptor() {
return new MyInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/assets/**");
}
}
方式二:
@ComponentScan({"programmer.lp.controller", "programmer.lp.interceptor"})
@EnableWebMvc
public class SpringMVCConfiguration implements WebMvcConfigurer {
@Autowired
private MyInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/assets/**");
}
}
纯注解—ViewResolver
XML配置:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/jsp"/>
<property name="suffix" value=".jsp"/>
</bean>
注解配置:
@ComponentScan({"programmer.lp.controller"})
@EnableWebMvc
public class SpringMVCConfiguration implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/page/jsp");
resolver.setSuffix(".jsp");
return resolver;
}
}
@Controller
@RequestMapping("/other")
public class OtherController {
@GetMapping("/demo1")
public String demo1() {
return "/welcome";
}
}
纯注解—路径后缀匹配
XML配置:
<mvc:annotation-driven>
<mvc:path-matching suffix-pattern="false"/>
</mvc:annotation-driven>
注解配置:
@ComponentScan({"programmer.lp.controller", "programmer.lp.interceptor"})
@EnableWebMvc
public class SpringMVCConfiguration implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false);
}
}
纯注解—响应乱码
XML配置:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
注解配置:
@ComponentScan("programmer.lp.controller")
@EnableWebMvc
public class SpringMVCConfiguration implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
stringConverter.setDefaultCharset(StandardCharsets.UTF_8);
MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
jacksonConverter.setDefaultCharset(StandardCharsets.UTF_8);
converters.add(stringConverter);
converters.add(jacksonConverter);
}
}
纯注解—请求乱码
web.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_4_0.xsd"
version="4.0">
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
注解形式:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVCConfiguration.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
FilterRegistration.Dynamic encodingFilter =
servletContext.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
encodingFilter.setInitParameter("encoding", "UTF-8");
encodingFilter.addMappingForUrlPatterns(null, false, "/*");
}
}
纯注解—Converter
Converter:
public class DateConverter implements Converter<String, Date> {
private Set<String> formats;
public void setFormats(Set<String> formats) {
this.formats = formats;
}
@Override
public Date convert(String dateStr) {
if (null == formats || formats.isEmpty()) return null;
for (String format : formats) {
try {
return new SimpleDateFormat(format).parse(dateStr);
} catch (Exception e) {
System.out.println("不支持:<" + format + ">格式!");
}
}
return null;
}
}
XML配置:
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="programmer.lp.converter.DataConverter">
<property name="patterns">
<set>
<value>yyyy-MM-dd</value>
<value>yyyy/MM/dd</value>
<value>yyyy年MM月dd日</value>
</set>
</property>
</bean>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"/>
注解配置:
由于该DateConverter有可能不止SpringMVC会用到,因此将其放到SpringConfiguration中:
public class SpringConfiguration {
@Bean
public DateConverter dateConverter() {
DateConverter dateConverter = new DateConverter();
Set<String> set = new LinkedHashSet<>();
set.add("yyyy-MM-dd");
set.add("yyyy/MM/dd");
set.add("yyyy年MM月dd日");
dateConverter.setFormats(set);
return dateConverter;
}
}
@ComponentScan("programmer.lp.controller")
@EnableWebMvc
public class SpringMVCConfiguration implements WebMvcConfigurer {
@Autowired
private DateConverter dateConverter;
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(dateConverter);
}
}
纯注解—MultipartResolver
不要忘记添加依赖,pom.xml:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
XML配置:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
</bean>
注解配置:
@ComponentScan("programmer.lp.controller")
@EnableWebMvc
public class SpringMVCConfiguration implements WebMvcConfigurer {
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
return resolver;
}
}
纯注解—Initializer的本质
Initializer取代web.xml—直接实现WebApplicationInitializer
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext springCtx =
new AnnotationConfigWebApplicationContext();
springCtx.register(SpringConfiguration.class);
servletContext.addListener(new ContextLoaderListener(springCtx));
AnnotationConfigWebApplicationContext mvcCtx =
new AnnotationConfigWebApplicationContext();
mvcCtx.register(SpringMVCConfiguration.class);
ServletRegistration.Dynamic servlet = servletContext.addServlet(
"DispatcherServlet",
new DispatcherServlet(mvcCtx));
servlet.setLoadOnStartup(0);
servlet.addMapping("/");
FilterRegistration.Dynamic encodingFilter = servletContext.addFilter(
"CharacterEncodingFilter",
new CharacterEncodingFilter("UTF-8"));
encodingFilter.addMappingForUrlPatterns
(null, false, "/*");
}
}
参考
小码哥-李明杰: Java从0到架构师③进阶互联网架构师.
本文完,感谢您的关注支持!
|