SSM框架
1、Spring框架
MVC开发模式:
jsp+servlet+jdbc
M:Model-模型层:jdbc
V:View-视图层:jsp
C:Controller-控制层:Servlet
SSM:springmvc4+spring4+Mybatis3
M:Model-模型层:mybatis
V:View-视图层:jsp
C:Controller-控制层:Controller(springmvc)
package:控制层(Controller)->业务层(spring)->模型层(mybatis)
1.1、IOC
IOC分别控制反转和依赖注入。
所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
控制反转(IOC:Inversion of Control):将对象的实例化交由spring来负责创建,说白了就是在xml中配置对象的bean实例。
依赖注入(DI: Dependency injection):在创建对象实例时,为这个对象注入属性值或其它对象实例。
1.1.1、依赖注入方式:(配置版)
-
设值注入:通过setXxx()方法注入(个人推荐:可以灵活组合)
1、需要使用setXxx()方法,在application.xml文件中使用
UserServiceImpl.java中
public class UserServiceImpl implements UserService { // private UserDao userDao=new UserDaoImpl();//死代码 private UserDao userDao; private String name; private String sex; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void setName(String name) { this.name = name; } public UserServiceImpl() { } public UserServiceImpl(UserDao userDao, String name,String sex) { this.userDao = userDao; this.name = name; this.sex=sex; } @Override public int addUser(User entity) { System.out.println("name:"+name+",sex:"+sex); return userDao.addUser(entity); } }
application.xml中:
<bean id="userService" class="com.ioc.conf.service.impl.UserServiceImpl"> <!-- 设值注入 --> <property name="userDao" ref="userDao" /> <property name="name" value="张三" /> </bean>
-
构造注入:通过构造方法注入
UserServiceImpl.java中需要提供构造函数
application.xml中
<bean id="userService" class="com.ioc.conf.service.impl.UserServiceImpl"> <!-- 构造注入 --> <!-- index:配置对应构造参数的位置,从0开始 <constructor-arg index="0" ref="userDao" /> <constructor-arg index="2" value="男" /> <constructor-arg index="1" value="张三" /> --> </bean>
-
p命名空间注入:
第一步:需要p命名空间的声明
xmlns:p="http://www.springframework.org/schema/p"
第二步:使用
<!-- p命名空间注入 --> <!-- p:属性名:配置的常量值 p:属性名-ref:配置引用类型的名称 --> <bean id="country1" class="com.ioc.conf.entity.Country" p:name="中国" /> <bean id="user1" class="com.ioc.conf.entity.User" p:id="1" p:loginName="admin" p:password="123" p:country-ref="country1" />
1.1.2、singleton和prototype
singleton:单例(默认值)
prototype:多例
<bean id="userService" class="com.ioc.conf.service.impl.UserServiceImpl"
scope="prototype">
</bean>
1.1.3、自动装配
spring提供了4种自动装配类型
取值 | 说明 |
---|---|
no | 默认值,spring默认不进行自动装配,必须显示指定依赖对象 |
byType | 根据属性类型自动装配,如果找到多个报错,只有找到唯一的那个,才会自动注入。如果找不到,什么也不做。 |
byName | 根据属性名称自动装配,找到bean的id值与属性名相同会自动注入。如果找不到,什么也不做。 |
constructor | 和byType类似,不过它针对的构造方法。如果找到1个 bean和构造方法的参数类型相匹配,则通过构造注入,否则什么也不做。 |
<!-- 第一种:在每个bean中通过autowire属性进行配置 -->
<bean id="userService2" class="com.ioc.conf.service.impl.UserServiceImpl"
scope="prototype" autowire="constructor">
<!-- <property name="userDao" ref="userDao" /> -->
<!-- <property name="name" value="张三" /> -->
</bean>
<!-- 第二种:直接在<beans>标签上配置default-autowire="default“ -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"
default-autowire="default">
</beans>
注意:不推荐使用,自动装配使得配置文件可以非常简洁,但同时也造成类型之间的依赖关系不明确,容易引发一些潜在的问题,在实际项目中需要谨慎使用。
1.1.4、基于注解的配置
- @Component:代表组件,表示1个bean实例
- @Controller:用于标注控制层
- @Service:用于标注业务层
- @Repository:用于标注模型层
- @Autowired:自动注入,byType(属于spring的注解)
- @Resource:自动注入,byName(属于j2ee的注解)
- @Qualifier:根据属性名注入:byName
- @Scope:配置singleton和prototype。
1.2、AOP
AOP(Aspect Oriented Programming):面向切面编程,在不改变原程序的基础上增加新的功能。
使用场景:做日志切面,权限切面。
AOP的增强方式有5种:
- befor:前置增强,在执行目标方法前触发
- after:最终增强,不管异常是否发生都一定会触发
- afterReturn:后置增强,如果发生异常不会被执行
- afterThrowing:异常增强,如果发生指定类型时触发
- around:环绕增强,前置增强和后置增强的综合体。
1.2.1、配置版
execution(* com.loongshawn.method.ces…* .*(…))
标识符 | 含义 |
---|---|
execution() | 表达式的主体 |
第一个“*”符号 | 表示返回值的类型任意 |
com.loongshawn.method.ces | AOP所切的服务的包名,即,需要进行横切的业务类 |
包名后面的“…” | 表示当前包及子包 |
第二个“*” | 表示类名,*即所有类 |
.*(…) | 表示任何方法名,括号表示参数,两个点表示任何参数类型 |
<!-- 配置aop -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(public * com.aop.conf.service.*.*(..))" id="pointcut"/>
<!-- 配置切面 -->
<!-- ref:配置执行切面的业务处理类 -->
<aop:aspect ref="serviceLogging">
<!-- 配置前置增强
<aop:before method="before" pointcut-ref="pointcut" />-->
<!-- 后置增强:如果发生异常不会执行 -->
<!-- returning:方法的参数名必须一致 -->
<aop:after-returning method="afterReturning" returning="returnVal" pointcut-ref="pointcut" />
<!-- 最终增强:不管是否发生异常都一定会执行 -->
<aop:after method="after" pointcut-ref="pointcut"/>
<!-- 异常增强 -->
<!-- throwing:值要与方法的参数名一致 -->
<aop:after-throwing method="afterThrowing" throwing="ex" pointcut-ref="pointcut"/>
<!-- 环绕增强 -->
<aop:around method="around" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
1.2.2、注解版
-
日志业务类
package com.aop.annotation.log; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect //面向切面 @Component //要加上类的bean的组件配置 public class ServiceLogging { private Log log = LogFactory.getLog(this.getClass()); @Pointcut("execution(public * com.aop.annotation.service.*.*(..))") public void myPointcut(){} // @Before("execution(public * com.aop.annotation.service.*.*(..))") @Before("myPointcut()") public void before(JoinPoint joinPoint){ log.info("前置增强处理被执行"); log.info("连接点对象:"+joinPoint.getTarget().getClass().getSimpleName()); log.info("连接点方法:"+joinPoint.getSignature()); log.info("连接点方法参数:"+joinPoint.getArgs()[0]); log.info("------------------"); log.debug("debug..."); log.info("info..."); log.warn("warn..."); log.error("error..."); log.fatal("fatal..."); } // @After("execution(public * com.aop.annotation.service.*.*(..))") @After("myPointcut()") public void after(){ log.info("最终增强处理被执行"); } @AfterReturning(pointcut="myPointcut()",returning="returnVal") public void afterReturning(Object returnVal){ log.info("后置增强处理被执行"); log.info("后置增强处理:方法返回值为:"+returnVal); } @AfterThrowing(pointcut="myPointcut()",throwing="ex") public void afterThrowing(Exception ex){ log.info("业务方法抛出了异常,异常增强处理被执行"); log.info("抛出的异常为:"+ex.getMessage()); } @Around("myPointcut()") public Boolean around(ProceedingJoinPoint pjp) throws Throwable{ log.info("环绕增强处理:目标方法执行前织入"); log.info("环绕增强处理:目标方法的参数:"+pjp.getArgs()[0]); Boolean b = null; if(true){ b = (Boolean)pjp.proceed(pjp.getArgs()); } log.info("环绕增强处理:目标方法的返回值为:"+b); log.info("环绕增强处理:目标方法执行后织入"); return b; } }
-
执行切入点的业务类
package com.aop.annotation.service.impl; import org.springframework.stereotype.Service; import com.aop.annotation.entity.User; import com.aop.annotation.service.UserService; @Service public class UserServiceImpl implements UserService { @Override public boolean addUser(User entity) { System.out.println("add User..."); // int i=1/0; return false; } }
-
测试类
package com.aop.annotation.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.aop.annotation.entity.User; import com.aop.annotation.service.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext-annotation.xml") public class TestUser { @Autowired //byType private UserService userService1; @Test public void test1(){ userService1.addUser(new User()); } }
2、Mybatis框架
2.1、简介
- 是apache的一个开源项目
- 是与Hibernate都属于ORM框架
- 小巧,简单易学
2.2、开发步骤
2.2.1、配置版
-
在pom.xml中配置依赖
<!-- mybatis orm related.....start --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.0</version> </dependency> <!-- mybatis orm related.....end --> <!--mysql数据库驱动 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency>--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <!-- project log related.....start --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
编写MyBatis配置文件的名称为:mybatis-config.xml
-
创建实体类和dao接口和dao实现类
-
编写mybatis的sql映射文件:xxxMapper.xml
-
编写测试类
2.2.2、注解版
- @Select:查询
- @Insert:新增
- @Update:修改
- @Delete:删除
2.3、缓存
-
一级缓存
在同一个session中,如果查询条件相同,则共享数据(只会在第1次查询时发出sql语句),默认开启的。
-
二级缓存
在不同的session中,能共享数据。
默认是不开启的。通过配置是可以实现二级缓存。
要开启二级需要完成的步骤:
-
第一步:要在mybatis的主体配置文件
mybatis-config.xml
中配置全局开启二级缓存<!-- 添加配置信息 --> <settings> <!-- 开启二级缓存 --> <!-- 如果全局二级缓存默认为flase,设置为true时开启 --> <setting name="cacheEnabled" value="true"/> </settings>
-
在sql映射文件中配置二级缓存策略:
xxxMapper.xml
<!-- 配置二级缓存策略 --> <!-- eviction:配置缓存策略 LRU(默认):最近最少使用,移除最长时间不使用的对象 FIFO:先进先出,将对象进入缓存的顺序来移除 flushInterval:刷新缓存的时间,指定的是具体的值(不能使用60*100) size:设置缓存的对象的数量,默认是1024 readOnly:设置返回的对象是只读的 --> <cache eviction="FIFO" flushInterval="6000" size="512" readOnly="true" />
-
3、Springmvc
3.1、springmvc的开发步骤:
-
在pom.xml中引入springmvc的相关依赖
-
创建Controller类
-
在src/main/resouces下创建applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd"> <!-- spring扫描组件 --> <context:component-scan base-package="com"> <!-- 排除扫描com.controller --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>
-
在WEB-INF/下创建springmvc的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd"> <!-- spring扫描组件 --> <context:component-scan base-package="com.controller" /> <!-- mvc:annotation-driven会自动注册AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter --> <mvc:annotation-driven> <!-- 注册JASON转换器 --> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"/> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </mvc:message-converters> </mvc:annotation-driven> </beans>
-
配置web.xml中加入spring和springmvc的配置
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name>Archetype Created Web Application</display-name> <!-- 配置web.xml,使其具有springmvc特性,主要配置两处, 一个是ContextLoaderListener,一个是DispatcherServlet --> <!-- 1、配置spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext.xml</param-value> </context-param> <!-- 配置ContextLoaderListener表示,该工程要以spring的方式启动。 启动时会默认在/WEB-INF目录下查找applicationContext.xml 作为spring容器的配置文件,该文件里可以初始化一些bean --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 字符集过滤器 start --> <filter> <filter-name>encodingFilter</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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 除了加过滤器,由于tomcat默认编码ISO-8859-1, 还需要修改 %tomcat%/conf/server.xml Connector 标签加属性 URIEncoding="UTF-8" --> <!-- 字符集过滤器 end --> <!-- spring mvc 配置 --> <!-- 配置DispatcherServlet表示,该工程将采用springmvc的方式。 启动时也会默认在/WEB-INF目录下查找XXX-dispatcher.xml作为配置文件, XXX就是DispatcherServlet的名字,该文件中将配置两项重要的mvc特性: HandlerMapping,负责为DispatcherServlet这个前端控制器的请求查找Controller; ViewResolver,负责为DispatcherServlet查找ModelAndView的视图解析器。 此处使用指定的配置文件spring-mvc.xml --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/*-dispatcher.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 如果这里是*.do就会有问题:静态资源文件放在Web-inf下需要能访问需要这里配置成/ <url-pattern>/</url-pattern> --> <url-pattern>*.json</url-pattern> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
-
创建jsp页面完成业务功能。
3.2、上传和下载
3.2.1、上传文件
-
form表单:upload.jsp
method必须为post
enctype=“multipart/form-data”
<form action="" method="post" enctype="multipart/form-data"> <input type="file" name="uploads" /> </form>
-
实现上传文件的Controller
-
在springmvc的配置中需要配置上传文件的配置信息
<!-- 配置上传文件 id属性必须为multipartResolver,否则报错--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 上传文件的最大值 --> <property name="maxUploadSize" value="5000000" /> <property name="defaultEncoding" value="utf-8" /> </bean>
-
将上传成功后的文件名在成功页面显示出来
3.2.2、文件下载
注意:
- 方法无返回值,数据是写入到响应流中
- 附件下载时显示的文件名中文会乱码,所以需要转码设置
package com.controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
//跳转到webapp/WEB-INF/jsp/jsp文件
@Controller //标注控制层
public class EmpController2 {
//下载文件
//method=RequestMethod.POST:约束当前请求只能是post请求
@RequestMapping(value="/download.do",method=RequestMethod.GET)
public void download(String fileName
,HttpServletResponse response
,HttpServletRequest request) throws Exception{
System.out.println("下载文件...fileName:"+fileName);
//1、设置下载参数
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//设置下载时显示的文件名,以及文件的打开方式
// inline:表示在线打开
// attachement:表示以下载文件的方式打开
// fileName:配置下载窗口打开时显示的文件名,文件名可能会有乱码
String tmpFileName=fileName;
tmpFileName=tmpFileName.replaceAll(" ", "");
System.out.println("tmpFileName:"+tmpFileName);
tmpFileName=new String(tmpFileName.getBytes("utf-8"),"iso-8859-1");
response.setHeader("content-disposition"
, "attachement;fileName="+tmpFileName);
//2、下载
InputStream is=null;
OutputStream os=null;
try {
//2.1、获得文件的根路径
String rootPath=request.getSession().getServletContext().getRealPath("/WEB-INF/static/upload");
System.out.println("rootPath:"+rootPath);
//2.2、获得读取文件的输入流
is=new FileInputStream(rootPath+"/"+fileName);
//2.3、获得响应流
os=response.getOutputStream();
//2.4、拷贝文件
IOUtils.copy(is, os);
os.flush();//刷新缓存
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.3、静态页面
如果某些页面不需要去后台获取数据,仅仅只是需要显示该页面,或者一些图片,js。这里你可以在 springmvc的配置文件中加入静态资源过滤
<!-- 对静态资源文件的访问 方案一 (二选一)
<mvc:default-servlet-handler/> -->
<!-- 对静态资源文件的访问 方案二 (二选一)
location:实际的资源文件的位置
mapping:对外的路径映射配置
-->
<!-- web.xml中springmvc的url配置为"*.do"下面这个/static/**不能访问 -->
<!-- web.xml中springmvc的url配置为"/"下面这个/static/**可以访问 -->
<mvc:resources mapping="/static/**" location="/WEB-INF/static/" />
3.4、拦截器
拦截器类似过滤器。
拦截器的实现步骤:
-
自定义拦截器继承
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
-
在springmvc的配置文件中添加自定义拦截器的配置
<!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 配置拦截的路径映射 --> <mvc:mapping path="/**" /> <!-- 配置自定义拦截器 --> <bean class="com.interceptor.PrivilegeInterceptor"> <property name="excludeUrlFilters"> <list> <value>/login.jsp</value> <value>/login.do</value> <value>/login2.do</value> </list> </property> </bean> </mvc:interceptor> </mvc:interceptors>
3.5、springmvc的数据验证
-
在pom.xml中加入验证的依赖包
<!-- springmvc实体类注解验证 start --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <!-- <version>2.0.0.Alpha1</version> --> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.4.Final</version> </dependency> <!-- springmvc实体类注解验证 end -->
-
在Controller方法中使用
//BindingResult与@Valid是配套使用,BindingResult的定义要放在@Valid后面 @RequestMapping("/login2.do") public ModelAndView login2(@Valid User user,BindingResult bindingResult ,HttpServletRequest request){ System.out.println("login2..."); ModelAndView view=new ModelAndView(); //1、判断注解是否有验证错误 if(bindingResult.hasErrors()){ StringBuffer sf=new StringBuffer(); for(ObjectError objectError:bindingResult.getAllErrors()){ String fieldName=((FieldError)objectError).getField(); String message=objectError.getDefaultMessage(); sf.append(fieldName+":"+message+"<br/>"); } view.addObject("errMsg", sf.toString()); view.setViewName("login"); }else{ HttpSession session=request.getSession(); session.setAttribute("userInfo", user); view.setViewName("index"); } return view; }
-
在实例Bean中通过注解来实现数据验证
package com.entity; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotBlank; public class User { private Integer id; private String loginName; private String password; public User() {} public User(Integer id, String loginName, String password) { this.id = id; this.loginName = loginName; this.password = password; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @NotBlank(message="登录名不能为空") public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } @NotBlank(message="密码不能为空") @Length(min=6,max=12,message="密码的长度必须在6~12之间") public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
[\u5927\u4E13|\u672C\u79D1|
[\aaaa-\aaaa]+专
4、SSM整合
4.1、Spring4+Mybatis3整合
整合步骤:
-
pom.xml中引入相关依赖
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- commons jar start --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.2</version> </dependency> <!-- commons jar end --> <!-- spring mvc related.....start --> <!-- TODO: replace jackson with fastjson --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.6.1</version> </dependency> <!-- springmvc实体类注解验证 start --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <!-- <version>2.0.0.Alpha1</version> --> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.4.Final</version> </dependency> <!-- springmvc实体类注解验证 end --> <!-- spring mvc related.....end --> <!-- mybatis orm related.....start --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <!-- mybatis orm related.....end --> <!--mysql数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <!-- db jar related.....end --> <!-- project log related.....start --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- project log related.....end -->
-
配置mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 添加配置信息 --> <settings> <!-- 打印sql语句 --> <setting name="logImpl" value="STDOUT_LOGGING"/> <!-- 如果列名是以"_"作为分隔符,那么可以开启驼峰命名规则 --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 开启二级缓存 --> <!-- 如果全局二级缓存默认为flase,设置为true时开启 --> <!-- 如果全局二级缓存设置为false,那么就算xxxMapper.xml中有配置二级缓存策略,那么也不会缓存 --> <setting name="cacheEnabled" value="flase"/> </settings> <!-- 为bean创建别名 --> <typeAliases> <typeAlias type="com.mybatis.conf.entity.Emp" alias="Emp" /> </typeAliases> </configuration>
-
配置mybais的sql映射文件:xxxMapper.xml
<?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"> <!-- namespace:命名空间,命名规则:包名+文件名 --> <mapper namespace="com.conf.dao.EmpDaoMapper"> <!-- 根据主键查询 --> <select id="findById" resultType="com.mybatis.conf.entity.Emp" parameterType="int"> select * from b_emp where empno=#{empno} </select> </mapper>
-
配置spring的配置文件:applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd"> <!-- spring扫描组件 --> <context:component-scan base-package="com"> <!-- 排除扫描com.controller --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 配置整合Mybatis --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 配置mybatis的主体配置文件 --> <property name="configLocation" value="classpath:mybatis-config.xml" /> <!-- 配置mybatis的sql映射文件 --> <property name="mapperLocations"> <list> <value>classpath:com/conf/dao/*Mapper.xml</value> </list> </property> <!-- 配置数据源 --> <property name="dataSource" ref="dataSource" /> </bean> <!-- mybatis-spring的第三方库中有为我们提供 sqlSessionTemplate --> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg ref="sqlSessionFactory"></constructor-arg> </bean> <!-- 引入外部文件:数据源的配置 --> <import resource="applicationContext-dataSource.xml" /> </beans>
-
创建Dao接口和实现类
-
创建Service接口和实现类
对于增、删、改操作要设置事务的传播行为:
传播行为 意义 PROPAGATION_MANDATORY 表示该方法必须运行在一个事务中。如果当前没有事务正在发生,将抛出一个异常 PROPAGATION_NESTED 理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立。而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。而Nested事务的好处是他有一个savepoint。 PROPAGATION_NEVER 表示当前的方法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异常。 PROPAGATION_NOT_SUPPORTED 表示该方法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该方法的运行期间被挂起。比如ServiceA.methodA的事务级别是PROPAGATION_REQUIRED ,而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED ,那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起,而他以非事务的状态运行完,再继续ServiceA.methodA的事务。 PROPAGATION_SUPPORTS 表示当前方法不需要事务性上下文,但是如果有一个事务已经在运行的话,它也可以在这个事务里运行。如果当前不在一个事务中,那么就以非事务的形式运行 PROPAGATION_REQUIRES_NEW 表示当前方法必须在它自己的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个方法运行期间被挂起。比如我们设计ServiceA.methodA的事务级别为PROPAGATION_REQUIRED,ServiceB.methodB的事务级别为PROPAGATION_REQUIRES_NEW,那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务,等待ServiceB.methodB的事务完成以后,他才继续执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。如果ServiceB.methodB失败回滚,如果他抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。 PROPAGATION_REQUIRED 表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。例如:如果serviceA.saveA()方法调用了serviceB.saveB()方法,那么假如这2个save都设置了PROPAGATION_REQUIRES事务传播行为,那么,saveB()会在saveA()开启的事务中运行。假如saveA()没有开启事务,那么saveB()会开启新的事务。 -
创建测试类
4.1.1、开启事务
4.1.1.1、注解版
-
在applicationContext.xml中配置事务管理和事务扫描
<!-- 通过spring来进行事务管理 --> <!-- 1、在没有将事务交由spring来管理时,使用sqlSessionTemplate这个类, 这种情况下,Mybatis进行增、删、改操作时,会自动提交事务,关闭session 2、将事务交由spring来管理,使用spring来提交事务 --> <bean id="txtManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 启动spring的注解扫描,开启事务 --> <tx:annotation-driven transaction-manager="txtManager" />
-
在xxxServiceImpl.java中配置@Transacational注解开启事务
package com.conf.service.impl; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.conf.dao.EmpDao; import com.conf.entity.Emp; import com.conf.service.EmpService; @Service("empService") //@Transactional(propagation=Propagation.REQUIRED) //写在类上,该类的所有public方法开启事务 public class EmpServiceImpl implements EmpService { @Autowired private EmpDao empDao; @Override public Emp findById(Integer empno) { return empDao.findById(empno); } @Transactional(propagation=Propagation.REQUIRED) //写在方法上,只有该方法开启事务 @Override public int saveEmp1(Emp entity) { int rows=empDao.saveEmp1(entity); int a=1/0; return rows; } }
4.1.1.2、配置版
-
在applicationContext.xml中配置事务管理和事务扫描
<!-- 通过spring来进行事务管理 --> <!-- 1、在没有将事务交由spring来管理时,使用sqlSessionTemplate这个类, 这种情况下,Mybatis进行增、删、改操作时,会自动提交事务,关闭session 2、将事务交由spring来管理,使用spring来提交事务 --> <bean id="txtManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置声明式事务 --> <!-- 配置通知 --> <tx:advice id="txtAdvice" transaction-manager="txtManager"> <tx:attributes> <tx:method name="find*" read-only="true" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="*" read-only="true" /> </tx:attributes> </tx:advice> <!-- 配置aop --> <aop:config> <aop:pointcut expression="execution(public * com.conf.service.*.*(..))," id="pointCut"/> <aop:advisor advice-ref="txtAdvice" pointcut-ref="pointCut" /> </aop:config>
-
在xxxServiceImpl.java中就不需要再使用@Transacational注解
4.1.2、Dao操作优化
4.1.2.1、第一种:通过sqlSessionTemplate完成
-
在applicationContext.xml中配置sqlSessionTemplate
<!-- Dao的操作: --> <!-- 第一种:通过sqlSessionTemplate实现 --> <!-- mybatis-spring的第三方库中有为我们提供 sqlSessionTemplate --> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg ref="sqlSessionFactory" /> </bean>
-
在xxxDaoImpl.java中使用sqlSessionTemplate调用mybatis的方法实现操作。
package com.conf.dao.impl; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.conf.dao.EmpDao; import com.conf.dao.mapper.EmpDaoMapper; import com.conf.entity.Emp; @Repository("empDao") public class EmpDaoImpl implements EmpDao { @Autowired private SqlSessionTemplate sqlSessionTemplate; @Override public Emp findById(Integer empno) { //2、执行操作 return sqlSessionTemplate.selectOne("com.conf.dao.EmpDaoMapper.findById",empno); } @Override public int saveEmp1(Emp entity) { return sqlSessionTemplate.insert("com.conf.dao.EmpDaoMapper.saveEmp1", entity); } }
4.1.2.2、第二种:通过MapperFactoryBean完成
第一种是调用sqlSessionTemplate完成的,但是这需要我们知道mybatis相关的API的方法才能实现。改进第一种。
-
在applicationContext.xml中配置
<!-- 第二种:通过MapperFactoryBean为每1个sql映射文件配置对应的Mapper接口实现 --> <!-- 为empDaoMapper接口配置Bean --> <bean id="empDaoMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> <property name="mapperInterface" value="com.conf.dao.mapper.EmpDaoMapper" /> </bean> <!-- 为deptDaoMapper接口配置Bean --> <bean id="deptDaoMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> <property name="mapperInterface" value="com.conf.dao.mapper.DeptDaoMapper" /> </bean>
-
在sql映射文件同包下创建对应的接口xxxMapper
EmpDaoMapper.java
注意:
- 接口的包名+类名与sql映射文件的namespace一致
- 接口的方法与sql映射文件的id一致
package com.conf.dao.mapper; import java.util.List; import java.util.Map; import com.conf.entity.Emp; /** * 1. 接口的包名+类名与sql映射文件的namespace一致 * 2. 接口的方法与sql映射文件的id一致 * @author Administrator * */ public interface EmpDaoMapper extends SqlMapper { /** * 根据主键查询 * @param empno * @return */ public Emp findById(Integer empno); /** * 新增:主键由程序指定 * @param entity * @return */ public int saveEmp1(Emp entity); }
-
在xxxDaoImp.java中使用配置的xxxMapper接口
package com.conf.dao.impl; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.conf.dao.EmpDao; import com.conf.dao.mapper.EmpDaoMapper; import com.conf.entity.Emp; @Repository("empDao") public class EmpDaoImpl implements EmpDao { // @Autowired // private SqlSessionTemplate sqlSessionTemplate; @Resource private EmpDaoMapper empDaoMapper; @Override public Emp findById(Integer empno) { //2、执行操作 // return sqlSessionTemplate.selectOne("com.conf.dao.EmpDaoMapper.findById",empno); return empDaoMapper.findById(empno); } @Override public int saveEmp1(Emp entity) { // return sqlSessionTemplate.insert("com.conf.dao.EmpDaoMapper.saveEmp1", entity); return empDaoMapper.saveEmp1(entity); } }
4.1.2.3、第三种:通过MapperScannerConfigure完成
第二种解决方法相对于第一种来说,有了很大的改进,但是在实际的企业项目中,有很多的sql映射文件,那么我们就需要在applicationContext.xml中配置很多的对应xxxMapper接口的bean,那么会导致配置文件内容的增多,而且繁琐。那么需要改进第二种解决方法。
-
创建SqlMapper接口
package com.conf.dao.mapper; /** * 父接口可以什么都不用写 * @author Administrator * */ public interface SqlMapper { }
-
将xxxMapper接口继承SqlMapper
public interface EmpDaoMapper extends SqlMapper { //... } public interface DeptDaoMapper extends SqlMapper { //... }
-
在applicationContext.xml中配置
<!-- 第三种:MapperScannerConfigure --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 扫描目录 --> <property name="basePackage" value="com.conf.dao.mapper" /> <!-- 配置Mapper的父接口 --> <property name="markerInterface" value="com.conf.dao.mapper.SqlMapper" /> </bean>
-
xxxDaoImpl.java中的代码不需要任何的修改。
4.2、 springmvc+spring+mybatis
步骤:
-
配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name>Archetype Created Web Application</display-name> <!-- 配置web.xml,使其具有springmvc特性,主要配置两处, 一个是ContextLoaderListener,一个是DispatcherServlet --> <!-- 1、配置spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext.xml</param-value> </context-param> <!-- 配置ContextLoaderListener表示,该工程要以spring的方式启动。 启动时会默认在/WEB-INF目录下查找applicationContext.xml 作为spring容器的配置文件,该文件里可以初始化一些bean --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 字符集过滤器 start --> <filter> <filter-name>encodingFilter</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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 除了加过滤器,由于tomcat默认编码ISO-8859-1, 还需要修改 %tomcat%/conf/server.xml Connector 标签加属性 URIEncoding="UTF-8" --> <!-- 字符集过滤器 end --> <!-- spring mvc 配置 --> <!-- 配置DispatcherServlet表示,该工程将采用springmvc的方式。 启动时也会默认在/WEB-INF目录下查找XXX-dispatcher.xml作为配置文件, XXX就是DispatcherServlet的名字,该文件中将配置两项重要的mvc特性: HandlerMapping,负责为DispatcherServlet这个前端控制器的请求查找Controller; ViewResolver,负责为DispatcherServlet查找ModelAndView的视图解析器。 此处使用指定的配置文件spring-mvc.xml --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/*-dispatcher.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 如果这里是*.do就会有问题:静态资源文件放在Web-inf下需要能访问需要这里配置成/ --> <url-pattern>/</url-pattern> <!-- <url-pattern>*.json</url-pattern> <url-pattern>*.do</url-pattern> --> </servlet-mapping> </web-app>
-
配置springmvc的配置文件:spring-dispatcher.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd"> <!-- spring扫描组件 --> <context:component-scan base-package="com.controller" /> <!-- mvc:annotation-driven会自动注册AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter --> <mvc:annotation-driven> <!-- 注册JASON转换器 --> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven> <!-- 配置视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <!-- 上面的配置是固定的,下面两个配置意思是:如果你要访问index视图, 它会自动 prefix(前缀) + index + suffix(后缀), 生成/WEB-INF/views/index.jsp WEB-INF下的资源文件是不能直接通过URL访问的,只能通过springmvc跳转后访问 --> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!-- 对静态资源文件的访问 方案一 (二选一) <mvc:default-servlet-handler/> --> <!-- 对静态资源文件的访问 方案二 (二选一) location:实际的资源文件的位置 mapping:对外的路径映射配置 --> <!-- web.xml中springmvc的url配置为"*.do"下面这个/static/**不能访问 --> <!-- web.xml中springmvc的url配置为"/"下面这个/static/**可以访问 --> <mvc:resources mapping="/static/**" location="/WEB-INF/static/" /> <mvc:resources mapping="/images/**" location="/images/" /> <!-- 配置上传文件 id属性必须为multipartResolver,否则报错 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 上传文件的最大值 --> <property name="maxUploadSize" value="5000000" /> <property name="defaultEncoding" value="utf-8" /> </bean> <!-- 配置拦截器 --> <!-- 配置拦截的路径映射 <mvc:mapping path="/**" /> 配置自定义拦截器 <bean class="com.interceptor.PrivilegeInterceptor"> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.interceptor.PrivilegeInterceptor"> <property name="excludeUrlFilters"> <list> <value>/login.jsp</value> <value>/login.do</value> <value>/login2.do</value> </list> </property> </bean> </mvc:interceptor> </mvc:interceptors>--> <!-- 不需要访问Controller可以直接跳转指定的页面 path:实际访问的路径 view-name:要跳转的路径 /upload: /WEB-INF/jsp/upload.jsp --> <mvc:view-controller path="/jsp/load_static_resource" view-name="/load_static_resource" /> </beans>
-
创建Controller类
-
写jsp页面
4.2.1、不经过Controller直接跳转到/WEB-INF/jsp/*.jsp的解决
测试的ur:http://localhost:8089/testSSM_final/jsp/load_static_resource
-
配置
<mvc:view-controller>
<!-- path:实际访问的路径 view-name:要跳转的路径 --> <mvc:view-controller path="/jsp/load_static_resource" view-name="/load_static_resource" />
-
必须配置视图解析器
<!-- 配置视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <!-- 上面的配置是固定的,下面两个配置意思是:如果你要访问index视图, 它会自动 prefix(前缀) + index + suffix(后缀), 生成/WEB-INF/views/index.jsp WEB-INF下的资源文件是不能直接通过URL访问的,只能通过springmvc跳转后访问 --> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean>
-
但是会导致通过Controller跳转不了
<mvc:annotation-driven>