一、SpringMVC了解
- springmvc的底层是Servlet,以Servlet为核心,接收请求,处理请求,显示处理结果给用户。
- DispatcherServlet 是框架一个Servlet对象,负责接收请求,响应处理结果。
- DispatcherServlet 他的父类是HttpServlet
- M:Model,模型层,指工程中的JavaBean,作用是处理数据
- V:View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据
- C:Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器
- MVC的处理模式是:用户通过视图层(View)将数据发送给服务器的控制层(Controller),控制层通过调用业务层在调用数据层去获取数据, 然后再将请求处理的结果返回给View视图层,最后视图层渲染数据响应给浏览器。
二、SpringMVC入门
2.1 springmvc配置
- 在springmvc.xml中配置
<!-- 添加注解扫描器 --> <context:component-scan base-package="com.meteor.controller"/> <!-- 添加视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置前缀 --> <property name="prefix" value="/admin/"/> <!-- 配置后缀 --> <property name="suffix" value=".jsp"/> </bean>
- 在web.xml中配置
<!-- 注册SpringMVC框架 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- 填写springmvx.xml配置文件的名称,让它去读取 --> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--注册Spring框架,目的就是启动spring容器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext_*.xml</param-value> </context-param>
2.2 解决post请求中文乱码问题
<!--添加中文编码过滤器 private String encoding; private boolean forceRequestEncoding; private boolean forceResponseEncoding; --> <filter> <filter-name>encode</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>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encode</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2.3 @RequestMapping注解
- 可以放在类的上面,相当于多加了一层路径
- 可以放在方法上面,表示请求的路径
- value可以默认不写,method默认是GET请求
- 参数最好使用包装类型,例如Integer,能接收空值情况,接收的是null
@RequestMapping(value = "/some.do", method= RequestMethod.GET) public ModelAndView doSome() {
接收请求参数:
- 使用restful方式,在超链接或者地址栏上提交数据时,需要使用@PathVariable这个注解来拿值
@RequestMapping("/hello/{name}/{age}") public String one(@PathVariable String name,@PathVariable Integer age) { return "main"; }
- 如果我们前端的名称和后端的名称不一致,则需要使用RequestParam注解来设置相对应的值
@RequestMapping("/hello") public String one(@RequestParam("name") String uname,@RequestParam("age") Integer uage) { return "main"; }
- 还可以使用老样子,用request.getParameter()方法来获取值
@RequestMapping("/hello") public String one(HttpServletRequest request) { String name = request.getParameter("name"); int age = Integer.parseInt(request.getParameter("age")); return "main"; }
- 当提交参数过多的时候,我们可以使用实体类来接收参数,但是在提交请求中,保证请求参数名称与实体类中成员变量名称一致,可以自动提交数据
@RequestMapping(value = "/test/receive-property.do") public ModelAndView doPropertyParam(User user) {
2.4 方法的返回值
- String:客户端资源的地址,自动拼装前缀和后缀,还可以屏蔽自动拼接字符串,可以指定返回路径
- Object:返回json格式的对象,自动将对象或者集合转为json,使用jackson工具进行转换,必须添加jackson依赖,一般用于ajax
- void:无返回值,一般用于ajax请求
- 基本数据类型,用于ajax请求
- ModelAndView:返回数据和视图对象,用的较少
- 当我们采用ajax方式请求的时候,需要配置注解驱动<mvc:annotation-driven/>,并且在类上加入@ResponseBody,也可以使用@RestController,它是@Controller + @ResponseBody
2.5 HttpMessageConverter 消息转换器
HttpMessageConverter接口:
- 可以将json数据转成java对象,同时也可以将java对象转成json字符串返回给前端
//把对象转为json ObjectMapper om = new ObjectMapper(); String json = om.writeValueAsString(student); System.out.println("json=" + json);
- 需要在springmvc的配置文件中,加入注解驱动的标签,mvc:annotation-driven 加入这个标签后,springmvc项目启动后,会创建HttpMessageConveter接口的7个实现类对象。包括StringHttpMessageConveter 和 Mappingjackson2HttpMessageConverter
三、请求转发和重定向
3.1 请求转发
- 请求转发的url地址栏是不变的
- 转发使用forward这个时候会清空我们的视图解析器配置,需要我们自己写明白具体的路径
@RequestMapping("/other") public String other() { System.out.println("访问了other"); return "main"; } @RequestMapping("/two") public String two() { System.out.println("请求转发action跳转"); // forward:这组字符串可以屏蔽前缀和后缀的拼接 return "forward:/other.do"; }
3.2 重定向
- 重定向的url是改变的,并且变得是最终请求的地址url
- 重定向无法携带数据,并且需要使用redirect,也要写明路径名称
@RequestMapping("/three") public String three() { System.out.println("这是重定向页面"); return "redirect:/admin/main.jsp"; } @RequestMapping("/four") public String four() { System.out.println("这是重定向action"); return "redirect:/other.do"; }
3.3 SpringMVC默认的参数类型
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Model
- Map
- ModelMap
- Model、Map、ModelMap和HttpServletRequest 一样,使用请求作用域进行数据传递,所以服务器跳转必须是请求转发。
- 这些参数我们都可以直接用,因为springmvc已经为我们准备好了。
四、SpringMVC资源处理问题
4.1 静态资源的处理方法
由于我们的中央调度器设置的是 "/":
使用 "/" 导致中央调度器是默认的 default servlet
需要处理静态资源和其他的为映射请求。 默认中央调度器没有处理静态资源的控制器对象,所以静态资源都是404.
some.do这个请求有MyController对象,所以能访问。
如果项目中,中央调度器设置了"/",动态资源能访问,静态资源不能访问,需要处理静态资源的访问工作。
注解式方法:
<!--声明注解驱动 default-servlet-handler和@RequestMapping使用有冲突 --> <mvc:annotation-driven /> <!--声明静态资源的第一种处理方式 创建DefaultServletHttpRequestHandler处理静态资源。 DefaultServletHttpRequestHandler把接收的静态资源的地址,转发给tomcat的default 优点:解决方式简单 缺点:依赖tomcat服务器提供的能力 --> <mvc:default-servlet-handler />
导入静态资源法:
- 在springmvc配置文件中加入一个 mvc:resources标签,框架会创建ResourceHttpRequestHandler控制器对象,使用这个对象处理静态资源的访问,不依赖tomcat服务器。推荐使用!
- 一句话设置静态资源
<mvc:resources mapping="/static/**" location="/static/" />
五、SpringMVC核心技术
5.1 拦截器
WEB-INF目录下的资源无法通过浏览器的url直接访问。都是通过controller的请求转发进行访问
但是这样也并不安全,因为我可以把它的请求路径记住,所以我们就需要用到了拦截器
拦截器的定义:
- 创建类实现拦截器接口 HandlerInterceptor,实现接口中的方法3个
- preHandle():在请求被处理之前进行操作
- postHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果
- afterCompletion:所有的请求响应结束后执行善后工作,清理对象、关闭资源、最终处理
- 在springmvc的配置文件中,声明拦截器对象,并置顶拦截的url地址
<!-- 注册拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <!-- 设置放行的请求 --> <mvc:exclude-mapping path="/shouLogin"/> <mvc:exclude-mapping path="/login"/> <!-- 配置具体的拦截器实现功能类 --> <bean class="com.meteor.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>
//拦截器 public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle先处理"); return true; } }
- 多个拦截器的时候也采用的是责任链设计模式,和我们JavaWeb部分的Filter过滤器一样,可以跳转到我的Tomcat深入浅出文章去了解一下
- 先执行过滤器、在执行中央调度器、最后才是拦截器。
- 一般拦截器都是用作登录拦截
5.2 异常处理机制
框架使用的是集中的异常处理。把各个Controller中抛出的异常集中到一个地方处理。处理异常的叫做异常处理器。
- @ControllerAdvice:放在类的上面,表示这个类中有异常的处理方法。相当于aop中的@Aspect
- @ExceptionHandler:放在方法的上面,表示此方法可以处理某个类型的异常。当异常发生时,执行这个方法。
@ControllerAdvice public class GlobalExceptionHandler { //定义处理异常的方法,当异常发生后,执行这个方法 /** *处理NameException类型的异常 * 参数: * @ExceptionHandler: 表示Controller抛出的异常对象 * 属性: value 异常的类型 */ @ExceptionHandler(value = NameException.class) public ModelAndView doNameException(Exception e) { //给用户友好的提示 ModelAndView mv = new ModelAndView(); mv.addObject("tips","姓名只能是zs"); mv.setViewName("nameError"); return mv; } }
- 我们可以通过这种方式去设置一个全局异常处理,也可以给某个单个异常进行处理。
六、SSM整合
6.1 整合思路
- 我们需要把java对象放到容器里,我们现在有两个容器
- Spring容器:管理service和dao等对象的,是业务层对象的容器。
- SpringMVC容器:管理控制器controller对象的,是视图层对象。
6.2 容器创建
Spring容器创建: 在web.xml中声明了ContextLoaderListener,这个功能是框架写好的,创建spring容器对象WebApplicationContext。在创建WebApplicationContext的时,就读取了spring的配置文件,当遇到bean标签的时候就将service、dao等对象创建好放到容器中。
SpringMVC容器创建: SpringMVC是Spring的子容器,它是用于将pojo实体类的对象创建出来的,操作的是Controller层
6.3 三层架构配置文件
application_mapper.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 读取属性文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 配置SqlSessionFactoryBean--> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <!--配置数据源--> <property name="dataSource" ref="dataSource"/> <!-- 配置SqlMapConfig.xml核心配置文件--> <property name="configLocation" value="classpath:SqlMapConfig.xml"/> <!--注册实体类--> <property name="typeAliasesPackage" value="com.meteor.pojo"/> </bean> <!-- 注册mapper.xml文件--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.meteor.mapper"/> </bean> </beans>
application_service.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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--添加包扫描--> <context:component-scan base-package="com.meteor.service.impl"></context:component-scan> <!--添加事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--切记切记:配置数据源--> <property name="dataSource" ref="dataSource"></property> </bean> <!--配置事务切面--> <tx:advice id="myadvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*select*" read-only="true"/> <tx:method name="*find*" read-only="true"/> <tx:method name="*serach*" read-only="true"/> <tx:method name="*get*" read-only="true"/> <tx:method name="*insert*" propagation="REQUIRED"/> <tx:method name="*add*" propagation="REQUIRED"/> <tx:method name="*save*" propagation="REQUIRED"/> <tx:method name="*set*" propagation="REQUIRED"/> <tx:method name="*update*" propagation="REQUIRED"/> <tx:method name="*change*" propagation="REQUIRED"/> <tx:method name="*modify*" propagation="REQUIRED"/> <tx:method name="*delete*" propagation="REQUIRED"/> <tx:method name="*drop*" propagation="REQUIRED"/> <tx:method name="*remove*" propagation="REQUIRED"/> <tx:method name="*clear*" propagation="REQUIRED"/> <tx:method name="*" propagation="SUPPORTS"/> </tx:attributes> </tx:advice> <!--配置切入点+绑定--> <aop:config> <aop:pointcut id="mycut" expression="execution(* com.meteor.service.impl.*.*(..))"></aop:pointcut> <aop:advisor advice-ref="myadvice" pointcut-ref="mycut"></aop:advisor> </aop:config> </beans>
springmvc.xml
//添加包扫描 <context:component-scan base-package="com.meteor.controller"/> //便于使用ajax <mvc:annotation-driven/>
- 分页的基本公式:基础分页公式:limit (当前页面-1)*每页条数,每页条数
全部评论
(1) 回帖