文章目录
SSM
-
静态资源排除
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping>
-
文件夹排除
<mvc:resources location="/layui/" mapping="/layui/**"></mvc:resources>
容器部件:
- @controller
- @service
- @repository
- @component
过程
- 浏览器发出请求
- 启动Spring容器:web.xml,请求地址能够被spring收到
- controller必须在spring容器里面(依赖在容器内,service)
- controller-service-dao-连接注入(必须在容器内)
- 核心:两个扫描(包扫描,数据库连接(MapperScannerConfigurer)扫描)
- RequestMapping 地址(多层地址,地址不能冲突)
- 方法参数冲突(int,integer必有项区别)
- 代码处理错误(null,index)- sql错误
- 返回的视图名称(路径对应)
- jsp视图处理正确
常见异常
- 404:mapping路径 / 视图名称 / 没进入spring处理
- 500:数据库异常(###:……)
- 500:控制器处理,根据异常信息
- 启动spring错误,依赖容器初始化错误
- web服务启动错误,jar包不完整,web.xml设置有问题,删除server重置
总结:
- 配置文件(包名正确)
- dao创建
- 创建接口:@Repository
- 创建增删改查方法,并加入对应注解,在注解中写sql语句,#{ 属性 }
- service创建 接口,方法一般与dao一致
- serviceImpl创建,类 引用service接口
加入注解@Service ,
加入@Autowired指定dao
实现每个方法的dao处理 - controller创建 @Controller
加入@Autowired 指定service
创建方法,指定@RequestMapping(“index”),执行方法
MVC
model(entity,pojo)
view
controller
-
基本处理
@Controller public class testController { @RequestMapping("aaa") public String index() { System.out.println("aaaa"); return "index"; }
-
@RequestMapping
@Controller 多级目录 @RequestMapping("Book") public class testController { @RequestMapping("index") public String index() {
-
方法参数
-
请求参数
public String index(String txt) public String index(Type t) 调用settters
-
系统参数
向页面模板传值(request 值) public String index(Type t,ModelMap m) m.put("info", new Type(2,"dddff")); public String index(HttpServletRequest req) public String index(HttpSession s)
-
-
方法数据库处理:@Autowired,在容器中根据类型自动获取对象
@Autowired 在容器中根据类型自动获取对象 Type_Dao dao; @RequestMapping("index") public @ResponseBody List<Type> index() { return dao.select(); }
-
方法返回
-
String:视图名称,
return "index";
-
String:URL转发,
return "redirect:index.jsp";
-
对象转json:
public @ResponseBody Type index() { return new Type(2,"dddff"); }
-
Mybatis
- ORM框架-对象关系映射
初始使用配置
-
创建数据源(不同的数据连接池)
<context:property-placeholder location="classpath:db.properties" /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="100"/> <property name="maxIdle" value="30"/> <property name="maxWait" value="500"/> <property name="defaultAutoCommit" value="true"/> <property name="connectionProperties"> <value>charSet=utf-8</value> </property> </bean>
-
创建sqlSessionFactory(创建连接会话工厂)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自动扫描mapping.xml文件 <property name="mapperLocations" value="classpath:com/situ/mapper/**.xml"></property> --> </bean>
-
扫描生成实现类(dao接口通过clib代理生成实现类)
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean>
-
数据库事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> //注解支持 <tx:annotation-driven transaction-manager="transactionManager"/>
注解模式
-
@Select
-
@Insert
-
@Update
-
@Delete
-
@Options:设置缓存时间;生成自增主键值
@Options(useGeneratedKeys = true, keyProperty = “id”)
public int insert(Type t)
必须有返回值,将自动编号列返回源对象的属性中
useGeneratedKeys 设置为"true"表明要 MyBatis 获取由数据库自动生成的主键;
keyProperty="id"指定把获取到的主键值注入到 XXX(实体类) 的 id 属性。@Options(useCache=true,flushCache=false,timeout=100000)
useCache = true表示本次查询结果被缓存以提高下次查询速度,
flushCache = false表示下次查询时不刷新缓存,
timeout = 10000表示查询结果缓存10000秒。
-
@Result:列指定映射
@Results( id="userMap", value={ @Result(column="id", property="id", id=true), @Result(column="user_name", property="userName"), @Result(column="user_password ", property="userPassword"), @Result(column="user_email", property="userEmail"), @Result(column="user_info", property="userInfo"), @Result(column="head_img", property="headImg", jdbcType=JdbcType.BLOB), @Result(column="create_time", property="createTime",jdbcType=JdbcType.TIMESTAMP) })
-
@ResultMap
上述Result的引用@ResultMap("userMap");
<resultMap type="Comment" id="CommentResult"> <association property="blog" select="selectBlog" column="blog" javaType="Blog"/> </resultMap> <select id="selectComment" parameterType="int" resultMap="CommentResult"> select * from t_Comment where id = #{id} </select> <select id="selectBlog" parameterType="int" resultType="Blog"> select * from t_Blog where id = #{id} </select>
-
@MapKey:指定map集合结果的key列
@MapKey("id") @Select("select * from user where hotel_address = #{address};") Map<Long, User> getUserByAddress(@Param("address") String address);
-
@Param:方法参数指定sql字段
@Select("select * from user where hotel_address = #{address};") List<User> getUserByAddress(@Param("address") String address);
xml模式:可与注解共用
-
设置改变
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/situ/mapper/**.xml"></property> </bean>
-
基本使用
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="dao.Type1_Dao"> <!-- xml与接口dao关联 --> <select id="select" resultType="model.Type" parameterType="java.lang.String"> select * from type ${_parameter} </select> <select id="selectById" resultType="model.Type" parameterType="int" > select * from type where id=#{id} </select> <insert id="insert" parameterType="model.Type"> insert into type(name) values(#{name}) </insert> </mapper>
-
sql拼接
<if>
使用<select id="select" resultType="model.Type" parameterType="java.lang.String"> select * from type <if test="_parameter!=null"> where id=9 </if> </select>
- choose,when,otherwise(switch 分支处理)
- foreach 循环
<foreach collection="" item="" index="" ></foreach>
- trim:规格化sql
where:查询后置是否添加 and / or
set:前置是否添加 / 修改时的set
定义接口
@Repository
public interface Type_Dao {
@Select("select * from type")
public List<Type> select();
@Insert("insert into type (name) values(#{name})")
public void insert(Type t);
两个扫描
- 将接口动态生成类,加入数据连接(包名一致)
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> ```
- 加入spring容器
<context:component-scan base-package="dao"></context:component-scan> ```
使用
- 动态注入:@Autowired,在容器中查找类型一致的对象,赋值到下面变量
TypeDao dao;
- 查询使用:
@RequestMapping("index") public @ResponseBody List<Type> index() { return dao.select(); } ```
- #{} 与 ${}的区别
- ${} 符号的作用是直接进行字符串拼接,小心sql注入
select * from book ${where}
- #{}替换预编译语句(PrepareStatement)中的占位符
select * from book where name = #{name}
- ${} 符号的作用是直接进行字符串拼接,小心sql注入
数据库事务管理
-
数据库事务管理器
<!-- transactionManager --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- enable transaction annotation support --> <tx:annotation-driven transaction-manager="transactionManager"/>
-
使用注解: @Transactional
-
事务处理类型
-
事物传播行为
@Transactional(propagation=Propagation.REQUIRED)
如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)@Transactional(propagation=Propagation.NOT_SUPPORTED)
容器不为这个方法开启事务@Transactional(propagation=Propagation.REQUIRES_NEW)
不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务@Transactional(propagation=Propagation.MANDATORY)
必须在一个已有的事务中执行,否则抛出异常@Transactional(propagation=Propagation.NEVER)
必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)@Transactional(propagation=Propagation.SUPPORTS)
如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.@Transactional(timeout=30) //默认是30秒
事物超时设置
-
事务隔离级别
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
读取未提交数据(会出现脏读, 不可重复读) 基本不使用@Transactional(isolation = Isolation.READ_COMMITTED)
读取已提交数据(会出现不可重复读和幻读)@Transactional(isolation = Isolation.REPEATABLE_READ)
可重复读(会出现幻读)@Transactional(isolation = Isolation.SERIALIZABLE)
串行化
-
-
方法中多条sql执行,其中一条失败,全部事务回滚
@Transactional(propagation=Propagation.REQUIRED) public void insert(Type t) { dao.insert(new Type(12, "1212")); dao.insert(new Type(12, "133")); }
-
Spring缓存
-
设置
<beans xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="myselect" /> </set> </property> </bean> <cache:annotation-driven mode="proxy" /> </beans>
-
@Cacheable: 如果有缓存就取缓存,否则查询数据库
@Select("select * from type ${txt} ${limit}") @Cacheable("myselect") public List<Type> select(@Param("txt") String txt,@Param("limit") String limit);
-
@CacheEvict:清楚指定缓存
@Insert("insert into type(id,name) values(#{id},#{name})")
@CacheEvict(value="myselect",allEntries=true)
public int insert(Type t);
- @CachePut:每次都查数据库,放入缓存,不检验之前的缓存状况
Spring(容器框架)
Bean管理:构建容器,Ioc:控制反转
-
bean标签:Spring配置文件解析
- id/ name:指定标识
- class:class位置(类全名)
- parent:指定通用对象 / abstract:该对象不直接创建,通用对象
- singleton=“true | false”:单例模式
- lazy-init=“true | false | default”:延迟处理
- autowire=“no | byName | constructor | autodetect | default”:自动注入
- init-method=“method” / destroy-method=“method” :springBean生命周期
- factory-method=“method” / factory-bean=“bean”> :设置工厂类,指定方法生产Bean
- dependency-check(依赖检查,默认为“default”):依赖检查
- none:不进行依赖检查。
- objects:只做对象间依赖的检查
- simple:只做原始类型和String类型依赖的检查
- all:对所有类型的依赖进行检查。它包括了前面的objects和simple。
- depends-on(依赖对象):这个Bean在初始化时依赖的对象,这个对象会在这个Bean初始化之前创建。
- ref:引用spring对象id或名称
- scope:构建作用域
- singleton:Spring IOC容器中只会存在一个共享的bean实例
- prototype:每一次使用到,都会产生一个新的bean实例
- request:每次请求到,都会产生一个新的bean实例
- session:每次新的会话,都会产生一个新的bean
- global session:每次新的目标源(门户,触发源)会话,都会产生一个新的bean
-
property:属性标签
- name:属性名称
- value:属性值,与ref互斥
- ref:引用spring对象id或名称
-
constructor-arg:构造参数
- index属性:指定构造参数的序号(从0开始)
- type属性:指定构造参数的类型
- ref / value属性
-
list / set / map / props
<list> <bean class=nMappingJackson2HttpMessageConvertern></bean> </list> <list> <value> Happy </value> <value>Smell</value> </list> <map> <entry key="1"> <ref bean="highTopic01n /> </entry> <entry key:"2" > <ref bean=nhighTopic02n /> </entry> </map> < props > <prop key= "driver">com.mysql.jdbc.Driver</prop> <prop key="url">jdbc:mysql://localhost:3306/test</prop> <prop key="usemamen>root</prop> <prop key="password">root</prop> </props> ```
DI依赖注入,装配
-
no:属性注入(手动)
<bean id="a1" class="model.Type"> <constructor-arg index="0" value="1"></constructor-arg> <constructor-arg index="1" value="小果冻"></constructor-arg> </bean> <bean class="model.Type2"> <property name="t" ref="a1"></property> </bean> ```
-
byType:根据属性的类型,自动查找部件装配
<bean id="a1" class="model.Type"> //Type2类中的t类型是Type,byType通过属性类型查找 <constructor-arg index="0" value="1"></constructor-arg> <constructor-arg index="1" value="小果冻"></constructor-arg> </bean> <bean class="model.Type2" autowire="byType"> </bean> ```
-
byName:根据属性的名称(id / name),自动查找部件装配
<bean id="t" class="model.Type"> //id名和Type2类中的属性名相同,byName通过属性名查找 <constructor-arg index="0" value="1"></constructor-arg> <constructor-arg index="1" value="小果冻"></constructor-arg> </bean> <bean class="model.Type2" autowire="byName"> </bean> ```
-
constructor:根据构造参数的类型,自动查找部件装配到构造方法;如果都未符合,将使用默认构造方法创建
public Type2(Type t) { super(); this.t = t; } ``` ```xml <bean class="model.Type"> //根据构造方法的参数进行选择 <constructor-arg index="0" value="1"></constructor-arg> <constructor-arg index="1" value="小果冻"></constructor-arg> </bean> <bean class="model.Type2" autowire="constructor"> </bean> ```
-
autodetect:byType和constructor选择,有默认构造方法
AOP面向切面开发(OOP面向对象开发)
切面在SSM中只针对serviceImpl包(service接口实现类包)
切面表达式不能指定全部方法(会出异常,执行切面多次)
- 概念
- Target:源对象
- Proxy:代理(源对象的包装,内容有源对象)
- Pointcut:切点(切面切入的条件筛选)
- Joinpoint:连接点(消息中接收的上下文对象)
- Advice:通知(切入的内容)
- Weaving:织入(将通知切入的过程)
- Aspect:层(放置通知的类)
- 切面类型:
- 前置切面:方法执行之前
- 后置切面:方法执行之后
- 返回切面:方法执行成功正常返回时
- 环绕切面:执行前后都可以
- 异常切面:方法执行中出现异常
- 接口切面:
- 必须创建接口
- 通知切面指定
- MethodBeforeAdvice:前置
- AfterReturningAdvice:返回
- MethodInterceptor:环绕
- ThrowsAdvice:异常
- 执行步骤
-
创建接口
-
目标类引用接口(代理对象自动与目标类使用相同接口)
-
创建通知类,引用通知切面接口
-
填写接口方法
public class myaspect implements MethodBeforeAdvice,AfterReturningAdvice,MethodInterceptor,ThrowsAdvice { public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("之前执行。。。。"); } public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("正常返回---"+returnValue); } public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("环绕前"); Object o= invocation.proceed(); System.out.println("环绕后"); return o; } // 异常切面的方法不是接口自带的,方法名,参数不能改动 public void afterThrowing(Method method, Object[] args, Object target, Exception ex) { System.out.println("出错了"); } ```
-
xml设置
<bean id="t" class="model.Type"> <!-- 目标对象 --> <constructor-arg index="0" value="1"></constructor-arg> <constructor-arg index="1" value="日日日日"></constructor-arg> </bean> <bean id="p" class="model.myaspect"></bean> <!-- 消息对象 --> <!-- 代理对象 (接口指定,通知指定,目标指定)--> <bean id="obj" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>model.TypeInterface</value> </property> <property name="interceptorNames"> <list> <value>p</value> </list> </property> <property name="target" ref="t"> </property> </bean> ```
-
代理调用
@Resource(name="obj") TypeInterface t; //必须是接口 @Test public void ee(){ System.out.println(t.getName()); } ```
-
- 动态代理切面
-
创建切面类
- gettarget获取的类名是被代理类的类名,换而言之 在编译完成之后,gettarget返回的对象是以被代理类的字节码文件存在着的,
- 而getthis的类名则代理类的类型,在编译完成后,getthis返回的对象是以代理类字节码文件存在着的。
public class aspect1 { public void aa(JoinPoint p) throws Throwable{ System.out.println(p.getTarget().getClass().getName()); //获取被代理类(getTarget) System.out.println(p.getThis().getClass().getName()); //获取代理类(getThis) System.out.println("前置......."); } public void bb(JoinPoint p,Object result) throws Throwable{ System.out.println("返回......."); } public void cc(JoinPoint p) throws Throwable{ System.out.println("后置......."); } public void dd(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("h前置......."); pjp.proceed(); System.out.println("h后置......."); } public void ee( JoinPoint jp, Throwable e) throws Throwable{ System.out.println("出错了"+e.getMessage()); } ```
-
xml配置(使用时,直接用源对象,已经动态代理重置)
<bean id="p" class="model.aspect1"></bean> <!-- 消息对象 --> <aop:config> <aop:aspect ref="p"> <aop:pointcut id="pointcut" expression="execution(public * *(..))" /> <aop:before method="aa" pointcut-ref="pointcut" /> <aop:after-returning method="bb" pointcut-ref="pointcut" returning="result" /> <aop:after method="cc" pointcut-ref="pointcut" /> <aop:around method="dd" pointcut-ref="pointcut" /> <aop:after-throwing method="ee" pointcut-ref="pointcut" throwing="e" /> </aop:aspect> </aop:config> ```
-
- annotation切面
-
xml配置
<context:component-scan base-package="model"></context:component-scan> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> ```
-
aspect类
@Component @Aspect public class dtaspect { @Pointcut("execution(public * *(..))") public void anyMethod() { } @Before(value = "anyMethod()") public void exe(JoinPoint p) throws Throwable{ System.out.println("前置......."); } @After(value = "anyMethod()") public void exe1(JoinPoint p) throws Throwable{ System.out.println("后置......."); } @AfterReturning(value = "anyMethod()",returning="o") public void exe2(JoinPoint p,Object o) throws Throwable{ System.out.println("后置1......."); } @Around(value = "anyMethod()") public void exe34(ProceedingJoinPoint p) throws Throwable{ System.out.println("h前置......."); p.proceed(); System.out.println("h后置......."); } @AfterThrowing(value = "anyMethod()",throwing="o") public void exe2(JoinPoint p,Throwable o) throws Throwable{ System.out.println("错误......."+o.getMessage()); } ```
-
调试
-
代码加载spring容器
ApplicationContext act = new ClassPathXmlApplicationContext("aa.xml"); Type t = (Type) act.getBean("a1"); ```
-
junit测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:aa.xml"}) public class JunitTest { @Autowired Type t; @Resource(name = "a1") Type t2; @Test public void ee() { System.out.println(t.getName()); System.out.println(t2.getId()); } } ```
获取容器部件
-
Autowired:根据byType
@Qualifier(value=“id标识”) Value属性可以按照id唯一标识注入@Autowired Type t; ```
-
Resource:根据byName
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.2</version> </dependency> ``` ```java @Resource(name="my") Type2 t2; ```
-
Inject&Named:根据2种
<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> ``` ```java @Inject Type my; @Inject @Named("my") Type2 aa; ```
切面表达式
- 任意公共方法的执行:
execution(public * *(..))
- 任何一个以“set”开始的方法的执行:
execution(* set*(..))
- AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
- 定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))
- 定义在service包或者子包里的任意方法的执行:
execution(* com.xyz.service..*.*(..))
- 在service包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service.*)
- 在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service..*)
SpringMVC
常用注解
-
容器部件
-
@Controller:控制器声明
-
@Service:逻辑层声明
-
@Repository:Dao层声明
-
@Component:其它类加入容器
-
@Configuration:初始设置声明
-
@Bean声明在方法,方法返回值到容器,与@Configuration组合使用
可以在容器部件创建时生成@Configuration public class AppConfig { @Bean public TransferService transferService() { return new TransferServiceImpl(); } }
等效于:
<bean id="transferService" class="com.acme.TransferServiceImpl"/>
-
@ComponentScan
-
@Scope:部件有效范围
-
@Lazy:延迟加载
-
@PostConstruct:初始化方法
-
@PreDestroy:销毁的方法
-
@ControllerAdvice:全局异常处理
@ControllerAdvice //全局异常处理 public class allExceptionRunner { @ExceptionHandler public ModelAndView allException(Exception e){ 根据异常类型,转移到不同错误页 if(e instanceof NullPointerException) { } } }
-
-
请求回应
-
@RequestMapping:所有请求进入
- value: 指定请求的实际地址
- method: 指定请求的method类型 RequestMethod.GET
- consumes: 指定处理请求的提交内容类型(Content-Type ,例如application/json, text/html)
- produces: 指定返回的内容类型
- params: 指定request中必须包含某些参数值是,才让该方法处理
params=“id=1” ;param=“id”; param={“id”,“name”} - headers: 请求头部数据 headers=“Referer=http://www.ifeng.com/”
- 其他请求的发送:
-
<form action="sp" method="post">
//必须为post -
<input type="hidden" name="_method" value="DELETE"></input>
<filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
@DeleteMapping("sss") public void aaa() { System.out.println("ddddd"); }
-
-
@GetMapping:GET请求进入
-
@PostMapping:POST请求进入
-
@DeleteMapping
-
@PutMapping
-
@PathVariable 从路径中获取参数
RESTFUL web设计模式
网址/Book/1
GET请求 获取
网址/Book/1
PUT请求 修改
网址/Book
POST请求 新增
网址/Book/1
DELETE请求 删除@GetMapping("sss/{myid}") public void aaa(@PathVariable("myid") int id) { System.out.println(id); }
-
@RequestParam:将请求参数的值放入方法参数
public void aaa(@requestParam("myid") int id) 请求转方法参数 System.out.println(id); } defaultvalue 设置默认值 required = true 设置必有项
-
@ModelAttribute modelmap的值的处理
-
方法前(每次请求前执行方法,类似于初始化请求)
@ModelAttribute("all") 返回值加入model public int aaass() { System.out.println("ddddd"); return 300; } @GetMapping("sss") public void aaa( int id,ModelMap m) { System.out.println(m.get("all")); }
-
注释方法参数,从model取值到方法参数
public void aaa(@ModelAttribute("all") int id,ModelMap m)
-
-
@SessionAttribute
-
注释一个类(指定名称的map值的添加,自动添加一份到session)
@SessionAttributes("user") public class BookController { @GetMapping("sss") public void aaa(Model s) { s.addAttribute("user", "aaaa11a"); }
-
注释方法参数,从session取值到方法参数
public void aaa(@SessionAttribute("user") String id,ModelMap m)
-
-
@ExceptionHandler:当控制器内出现异常时自动执行
@ExceptionHandler public void test(Exception e) { e.printStackTrace(); }
-
@ResponseBody:将返回值作为回应的内容,自动转json
public @ResponseBody String test() { return "json"; //object将自动转为json }
-
@RestController
-
@RequestBody:将请求内的内容转为参数,数组,集合,复杂对象
-
发送:最好Ajax
function testajax(){ $.ajax({ headers: { 'Content-Type': 'application/json' }, type: "post", url: "Book/sss.action", data: JSON.stringify([{name:"a1"},{name:"a2"}]), success: function (data) { }, error: function (data) { } }); }
-
接收方:
@RequestMapping("sss") public void aaa(@RequestBody List<Type> ts ) { System.out.println(ts.size()); for(Type t:ts) System.out.println(t.getName()); }
-
-
文件上传
-
form
<form action="Upload" method="post" enctype="multipart/form-data"> <input type="file" name="file">
-
xml
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="104857600" /> <property name="maxInMemorySize" value="4096" /> <property name="defaultEncoding" value="UTF-8"></property> </bean>
-
控制器方法
public void aaa(@RequestParam("file") CommonsMultipartFile file ) file.transferTo(new File("目标位置"));
-
Form表单上传实例
@RequestMapping("sss") public void aaa(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest req )throws Exception { String oname=file.getOriginalFilename(); String ex=oname.substring(oname.lastIndexOf("."),oname.length()); String nname = UUID.randomUUID()+ex; String path=req.getSession().getServletContext().getRealPath("/"); path=new File(path).getParentFile().getPath()+"/upload"; System.out.println(path); file.transferTo(new File(path,nname)); }
-
Ajax文件上传实例
function openfile(){ $("[name=file]")[0].click(); } function upload(){ var formData = new FormData(); formData.append("file",$("[name=file]")[0].files[0]); $.ajax({ url:'Book/sss.action', type:'post', data: formData, contentType: false, processData: false, success:function(res){ $(".upimg").attr("src",res); } }); }
<button onclick="openfile();"> 测试 </button> <button onclick="upload();"> 上传 </button> <div> <img class="upimg" src=""> </div> <form method="post" action="Book/sss.action" enctype="multipart/form-data" style="display:none;"> <input type="file" name="file"> </form>
控制器方法
- 方法参数
- 用户参数
- 简单类型,基础类型,简单对象(get/set)
- 复杂类型,嵌套型对象,对象集合,map
设置enctype="application/json"
,请求参数数据位json字符串 - 文件上传
@RequestParam("file") CommonsMultipartFile file
- 服务器变量参数
@ModelAttribute("txt") String txt
- @modelattribute request值赋值参数
- @sessionattribute session值赋值参数
- 系统参数
- request 值栈,在el中使用,进行页面渲染
m.addAttribute(key,value); //重复时报异常
m.put(key,value); //重复时替换- model
- modelmap
- HttpservletRequest
- HttpServletResponse
- HttpSession
- request 值栈,在el中使用,进行页面渲染
- 用户参数
- 方法返回值
-
视图名称
返回 String
:指定视图名称无返回
:返回mapping路径作为视图名称
-
json返回 / html返回
- 必须使用:@ResponseBody / @RestController
- 将返回的对象转换为字符串
-
视图返回
@RequestMapping("aaa") public ModelAndView dsd() { ModelAndView view=new ModelAndView(); view.addObject("name", "而韩11国"); view.setViewName("Book/sss"); // view.setView(new JstlView(url)); return view; }
-
Spring拦截器
-
拦截器类
@Component public class myInterceptor implements HandlerInterceptor{ public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { //完成之后 System.out.println("完成之后"); } public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { //过程 System.out.println("过程"); } public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { //之前 System.out.println("之前"); return false; //false拦截取消请求 true可以进入方法 } }
-
xml配置
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/Book/*"/> <bean class="controller.myInterceptor" /> </mvc:interceptor> </mvc:interceptors>
-
顺序
filter(过滤器:请求)–>interceptor(拦截器:请求,控制器对象)–>aop(切面:请求,控制器对象,调用方法)
Spring 标签库,2套库
- 表单显示处理 form
- 数据处理:bind
编码乱码
- 文件编码:记事本
- IDE文件编码(*)
- Java编译编码(***)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- Web页面编码(***)
<meta charset="UTF-8">
- 请求编码:request对象 & get请求地址
- response编码
setContentType
- 数据库连接编码
useUnicode=true&characterEncoding=utf-8&autoReconnect=true
- 数据库引擎编码(****):my.ini设置,创建库表选择
- 编码改变
new String("abc".getBytes("IOS-8859-1"),"UTF-8");