回顾
1,AOP(注解)
常用的注解
@Aspect 声明切面
@Pointcut 定义切入点表达式
@Before 前置通知
@After 后置通知
@AfterReturning 返回后通知
@AfterThrowing 异常通知
@Around 环绕通知
开启aop注解驱动:
<aop:aspectj-autoproxy />
aop原理:
默认是判断是否实现接口,实现使用的是jdk动态代理,没有实现使用CGLIB代理。
我们也可以通过设置使无论是否实现接口都使用CGLIB代理
2,声明式事务
xml配置:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--定义事务管理的通知类-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!--定义控制的事务-->
<tx:attributes>
<tx:method name="*" read-only="false"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.itheima.service.*Service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
注解:
配置:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务注解驱动-->
<tx:annotation-driven/>
在service接口上添加注解
@Transactional(readOnly = true)
今日内容
- spring提供的模板对象
- JdbcTemplate(了解)
- RedisTemplate
- springmvc
- springmvc的介绍
- springmvc的入门案例
- 基本的配置
- 请求
- 响应
1,JdbcTemplate(知道)
2,RedisTemplate(了解)
回顾:
- redis是一个key-value对内存数据库
- key的类型只能是string类型
- vlue的类型有5中:
- string
- hash
- set
- list
- sortedset
使用:
-
引入jar包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.0.6.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.1.9.RELEASE</version> </dependency> </dependencies>
-
配置
jedis的配置类
@PropertySource("classpath:redis.properties") public class RedisConfig { @Value("${redis.host}") private String hostname; @Value("${redis.port}") private int port; @Bean public RedisTemplate getRedisTemplate(RedisConnectionFactory factory) { RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(factory); //redisTemplate.setKeySerializer(); return redisTemplate; } @Bean public RedisConnectionFactory getRedisConnectionFactory(JedisPoolConfig config) { JedisConnectionFactory factory = new JedisConnectionFactory(); factory.setHostName(hostname); factory.setPort(port); factory.setPoolConfig(config); return factory; } @Bean public JedisPoolConfig jedisPoolConfig() { JedisPoolConfig config = new JedisPoolConfig(); return config; } }
spring的主配置类
@Configuration @Import(RedisConfig.class) public class SpringConfig { }
-
操作不同结构数据的api:
redisTemplate.opsForValue(); //表明操作的是string类型 redisTemplate.opsForHash(); //表明操作的是hash类型 redisTemplate.opsForList(); //表明操作的是list类型 redisTemplate.opsForSet(); //表明操作的是set类型 redisTemplate.opsForZSet(); //表明操作的是sortedset类型
-
测试代码
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class RedisTemplateTest { @Autowired private RedisTemplate redisTemplate; @Test public void testString() { /*ValueOperations valueOperations = redisTemplate.opsForValue(); valueOperations.set("username","robin");*/ //redisTemplate.opsForValue().set("username","robin"); //创建User对象 User user = new User(); user.setUsername("robin"); user.setPassword("123"); //将user对象作为值存储到redis中 redisTemplate.opsForValue().set("user",user); } @Test public void testStringGet() { User user = (User) redisTemplate.opsForValue().get("user"); System.out.println(user); } }
可以设置key的序列化机制为String:
@Bean
public RedisTemplate getRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(factory);
//创建序列化对象
RedisSerializer serializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(serializer);
redisTemplate.setHashKeySerializer(serializer);
return redisTemplate;
}
注意:redisTemplate有默认的序列化机制。就是jdk的序列化机制。也就是要想将对象存储到redis,对象所属类必须实现Serializable
3,springMVC
3.1 MVC回顾
3.1 springmvc概述
是一个web层轻量级的框架。
3.2 入门案例
-
引入坐标
<dependencies> <!-- servlet3.1规范的坐标 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--jsp坐标--> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <!--spring的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> <!--spring web的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.9.RELEASE</version> </dependency> <!--springmvc的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.9.RELEASE</version> </dependency> </dependencies> <!--构建--> <build> <!--设置插件--> <plugins> <!--具体的插件配置--> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>80</port> <path>/</path> </configuration> </plugin> </plugins> </build>
-
编写controller类
@Controller public class UserController { //模块名称Controller //设定当前方法的访问映射地址 @RequestMapping("/save") //设置当前方法返回值类型为String,用于指定请求完成后跳转的页面 public String save(){ System.out.println("user mvc controller is running ..."); //设定具体跳转的页面 return "success.jsp"; } }
-
配置(web.xml)
<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
springmvc的核心配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--扫描加载所有的控制类类--> <context:component-scan base-package="com.itheima.controller"/> </beans>
3.3 springmvc结构
3.4 静态资源处理
-
方式1:
<mvc:resources mapping="/img/**" location="/img/"/> <mvc:resources mapping="/js/**" location="/js/"/> <mvc:resources mapping="/css/**" location="/css/"/>
上面配置对应的关系。
-
方式2:
<mvc:default-servlet-handler/> <!--将静态资源交由tomcat里面的DefaultServlet进行处理-->
上面配置的原理:
/和/*的区别:
/和/*匹配所有的请求路径,/ 排除jsp资源
3.5 乱码处理
-
post请求乱码处理
<!--乱码处理过滤器,与Servlet中使用的完全相同,差异之处在于处理器的类由Spring提供--> <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>
-
get请求乱码
tomcat7版本及以前的版本默认get请求使用的字符集是ISO-8859-1。tomcat8及以后的版本默认是UTF-8<!--构建--> <build> <!--设置插件--> <plugins> <!-- tomcat插件控制 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <!--端口控制--> <port>80</port> <!--虚拟目录--> <path>/</path> <!--编码(get请求方式)--> <uriEncoding>UTF-8</uriEncoding> </configuration> </plugin> </plugins> </build>
入门案例常见问题:
-
项目必须是web项目,打包方式war
<packaging>war</packaging>
-
servlet和jsp的包必须是高版本,并且只应用于编译器
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--jsp坐标--> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> <scope>provided</scope> </dependency>
-
springmvc只扫描Controller注解
@Controller
3.6 注解驱动(忽略)
4,请求
4.1 请求数据
4.1.1 普通类型
- 请求参数名和方法形参名称相同
- 请求参数名和方法形参名称不相同
4.1.2 pojo类型
4.1.3 集合类型
4.2 类型转换器
问题:
springmvc不能将日期数据疯转到Date对象中,因为springmvc默认支持的格式 是 yyyy/MM/dd.
解决方案:
-
配置
<!--开启注解驱动,加载自定义格式化转换器对应的类型转换服务--> <mvc:annotation-driven conversion-service="conversionService"/> <!--自定义格式化转换器--> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <!--覆盖格式化转换器定义规则,该规则是一个set集合,对格式化转换器来说是追加和替换的思想,而不是覆盖整体格式化转换器--> <property name="formatters"> <set> <!--具体的日期格式化转换器--> <bean class="org.springframework.format.datetime.DateFormatter"> <!--具体的规则,不具有通用性,仅适用于当前的日期格式化转换器--> <property name="pattern" value="yyyy-MM-dd"/> </bean> </set> </property> </bean>
-
注解
@DateTimeFormat(pattern = "yyyy-MM-dd") 可以使用在形式参数上,也可以使用在pojo的成员变量 <mvc:annotation-driven />
4.3 自定义类型转换器(了解)
需求: 将日期数据(date=2020/10/10)转换成long类型的数据.
解决:
要实现上面的需求,我们需要自定义类型转换器。
-
定义类型转换器的类
public class MyDateConverter implements Converter<String, Long> { //重写接口的抽象方法,参数由泛型决定 public Long convert(String source) { DateFormat df = new SimpleDateFormat("yyyy/MM/dd"); Date date = null; //类型转换器无法预计使用过程中出现的异常,因此必须在类型转换器内部捕获,不允许抛出,框架无法预计此类异常如何处理 try { date = df.parse(source); return date.getTime(); } catch (ParseException e) { e.printStackTrace(); } return null; } }
-
配置
<mvc:annotation-driven conversion-service="conversionService"/> <!--自定义类型转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <!--覆盖类型转换器定义规则,该规则是一个set集合,对类型转换器来说是追加和替换的思想,而不是覆盖整体格式化转换器--> <property name="converters"> <set> <!--添加自定义的类型转换器,会根据定义的格式覆盖系统中默认的格式--> <!--当前案例中是将String转换成Date的类型转换器进行了自定义,所以添加后,系统中原始自带的String——>Date的类型转换器失效--> <bean class="com.itheima.converter.MyDateConverter"/> </set> </property> </bean>
使用:
4.4 请求映射
@RequestMapping(“请求资源路径”)
可以使用在类上,也可以使用在方法上。
rsionServiceFactoryBean">
使用:
<img src="img/image-20200919172711440.png" alt="image-20200919172711440" style="zoom:67%;" />
### 4.4 请求映射
@RequestMapping("请求资源路径")
可以使用在类上,也可以使用在方法上。