servlet中央调度器配置文件
标题
l流程图
标题
接收请求参数
复习总结
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:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--springmvc配置文件 ,声明controller和其他web相关的对象-->
<!--配置扫描包路径-->
<context:component-scan base-package="com.gy.controller"/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--配置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置注解驱动-->
<mvc:annotation-driven/>
<!--
1.响应ajax请求,返回json
2.解决静态资源问题
-->
</beans>
spring配置文件
<?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
http://www.springframework.org/schema/context/spring-context.xsd">
<!--spring的配置文件 声明service,dao,工具类等对象-->
<context:property-placeholder location="classpath:conf/jdbc.properties"/>
<!--声明数据源,连接数据库-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 数据库基本信息配置 -->
<property name="url" value="${jdbc.url}"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 3.配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:conf/mybatis.xml" />
<!--<!– 扫描entity包 使用别名 –>
<property name="typeAliasesPackage" value="com.soecode.lyf.entity" />
<!– 扫描sql配置文件:mapper需要的xml文件 –>
<property name="mapperLocations" value="classpath:mapper/*.xml" />-->
</bean>
<!-- 4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.gy.dao" />
</bean>
<!--声明service的注解@service所在的包名位置-->
<context:component-scan base-package="com.gy.service"/>
<!--事务配置:注解的配置,aspectj的配置-->
</beans>
数据库配置文件
jdbc.url=jdbc:mysql://localhost:3306/xq?serverTimezone=GMT%2B8&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
mybatis主配置文件
<?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>
<!--setting:控制mybatis全局行为-->
<settings>
<!--设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--设置别名-->
<typeAliases>
<!--name:实体类所在包名-->
<package name="com.gy.domain"/>
</typeAliases>
<!--sql mapper(sql映射文件)的位置-->
<mappers>
<!--name:包名,这个包中的所有毛片儿.xml一次都能加载
使用package的要求
1.mapper文件名称和dao接口名称必须完全一样,包括大小写
2.mapper文件和dao接口必须在同一目录
-->
<package name="com.gy.dao"/>
</mappers>
</configuration>
逐个接收参数是用的方法
在逐个接收参数时,当请求中的参数名和处理器中(controller)的形参名不一样时
接收多个参数时,用对象的形式来接收
处理器方法的返回值
当我们手工实现ajax,json数据,代码有重复的 1.java对象转为json; 2.通过httpservletresponse输出json数据
返回值Object
处理器返回自定义类型
/*
* 处理器方法返回一个student,通过框架转为json,响应ajax请求
* @ResponseBody:
* 作用:把处理器方法返回对象转为json,通过HTTPServletResponse输出给浏览器
* 位置:方法的定义上面,和其他注解没有顺序关系
* 返回对象框架的处理流程:
* 1.框架会把返回student类型,调用框架中的ArrayList<HTTPMessageconverter>
集合中每个类的canWrite()方法
* 检查那个HTTPMessageConverter接口的实现类能处理student类型的数据--MappingJackson2HTTPMessageConverter
* 2.框架会调用实现类的write(),MappingJackson2HTTPMessageConverter的write()方法
* 把韩信同学的student对象转为json,调用Jackson的objectMapper实现转为json
* 3.框架会调用@ResponseBody把2的结果数据输出到浏览器,ajax请求处理完成
*
* */
@RequestMapping(value = "/StudentJson.do")
@ResponseBody
public student doStudentJsonObject(String name,Integer age){
//调用service,获取请求结果数据,Student对象表示结果数据
student student=new student();
student.setName("韩信");
student.setAge(20);
return student;//会被框架转为json
}
处理器返回list集合
/*处理器方法返回list<student>
* 处理器方法返回一个student,通过框架转为json,响应ajax请求
* @ResponseBody:
* 作用:把处理器方法返回对象转为json,通过HTTPServletResponse输出给浏览器
* 位置:方法的定义上面,和其他注解没有顺序关系
* 返回对象框架的处理流程:
* 1.框架会把返回list<student>类型,调用框架中的ArrayList<HTTPMessageconverter>
集合中每个类的canWrite()方法
* 检查那个HTTPMessageConverter接口的实现类能处理student类型的数据--MappingJackson2HTTPMessageConverter
* 2.框架会调用实现类的write(),MappingJackson2HTTPMessageConverter的write()方法
* 把韩信同学的student对象转为json,调用Jackson的objectMapper实现转为json
* 3.框架会调用@ResponseBody把2的结果数据输出到浏览器,ajax请求处理完成
*
* */
@RequestMapping(value = "/StudentJsonArray.do")
@ResponseBody
public List<student> doStudentJsonObjectArray(String name, Integer age){
List<student> list=new ArrayList<student>();
//调用service,获取请求结果数据,Student对象表示结果数据
student student=new student();
student.setName("韩信");
student.setAge(20);
list.add(student);
student =new student();
student.setName("赵云");
student.setAge(20);
list.add(student);
return list;//会被框架转为json
}
返回字符串对象
/*
* 处理器方法返回的是string,string表示数据的,不是视图
* 区分返回值string是数据,还是视图,看有没有@ResponseBody注解
* 如果有@ResponseBody注解,返回string就是数据,反之就是视图
*
* 默认使用的是text/plain;charset=ISO-8859-1作为contentType,导致中文有乱码
* 解决方案:给RequestMapping增加一个属性 produces,使用这个属性指定新的contentType.
*返回对象框架的处理流程:
* 1.框架会把返回string类型,调用框架中的ArrayList<HTTPMessageconverter>
集合中每个类的canWrite()方法
* 检查那个HTTPMessageConverter接口的实现类能处理string类型的数据--StringMessageConverter
* 2.框架会调用实现类的write(),StringMessageConverter的write()方法
* 把字符串按照指定的编码处理
* 3.框架会调用@ResponseBody把2的结果数据输出到浏览器,ajax请求处理完成
* */
@RequestMapping(value = "/returnString.do",produces ="text/plain;charset=utf8" )
@ResponseBody
public String doStringData(String name,Integer age){
return "Hello SpringMvc 返回对象,表示数据";
}
解决静态资源的方法
第一种
第二种
第二种处理静态资源方法
在处理器方法中写URL时也就不用在写 .do 了
<!-- 第一种处理静态资源的方法
需要在springmvc配置文件加入<mvc:default-servlet-handler />
原理是:加入这个标签后,框架会创建控制器对象DefaultServletHttpRequestHandler(类是我们自己创建的controller)
-->
<mvc:default-servlet-handler />
<!--第二种处理静态资源的方法:
mvc:resources加入后框架会创建ResourceHttpResquestHandler这个对象.
让这个对象处理静态资源的访问,不依赖tomcat服务器
mapping:访问静态资源的URL地址,使用通配符 **
location:静态资源在你的项目中的目录位置.
images/**:表示images/p1.jpg,images/user/p2.jpg,....
-->
<!--<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/html/**" location="/html/" />
<mvc:resources mapping="/js/**" location="/js/" />-->
<!--使用一个配置语句,指定多种静态资源的访问-->
<!--<mvc:resources mapping="/static/**" location="/static/" />-->
相对地址
框架整合
转发和重定向
forward和redirect都是关键字,他们有一个共同的特点,不和视图解析器一同工作
package com.gy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/*
* @Controller:创建处理器对象,对象放在springmvc容器中
* 位置:在类的上面
* 和spring中讲的@service,@Component
* */
@Controller
public class MyController {
/**
* 处理器方法返回modelAndview,实现转发forward操作
* 语法:setViewName("forward:视图文件完整路径")
* 特点:不和视图解析器一同使用,就当你的项目中没有视图解析器
* @return
*/
@RequestMapping(value = "/doForward.do")
public ModelAndView deSome(){//doget()--service请求处理
//处理some.do请求了相当于service调用处理完成了
ModelAndView mv = new ModelAndView();
//添加数据,框架在请求的最后把数据放入到request作用域
//request.setAttribute("msg","欢迎使用springmvc做web开发");
mv.addObject("msg","欢迎使用springmvc做web开发");
mv.addObject("fun","执行的是doSome方法");
//显示转发
//mv.setViewName("forward:/WEB-INF/view/show.jsp");
mv.setViewName("forward:/hello.jsp");
//返回mv
return mv;
}
/**
* 处理器方法返回modelAndview,实现转发Redirect操作
* 语法:setViewName("doRedirect:视图文件完整路径")
* 特点:不和视图解析器一同使用,就当你的项目中没有视图解析器
*
* 框架对重定向的操作:
* 1.框架会把Model中的简单类型的数据,转为string使用,作为hello.jsp的get请求参数使用
* 目的在于:doRedirect.do和hello.jsp 两次请求之间传递数据
* 2.在目标hello.jsp页面可以使用参数集合对象 ${param}获取请求参数值
* ${param.myname}
* @return
*/
@RequestMapping(value = "/doRedirect.do")
public ModelAndView doRedirect(String name,Integer age){//doget()--service请求处理
//处理some.do请求了相当于service调用处理完成了
ModelAndView mv = new ModelAndView();
//添加数据,框架在请求的最后把数据放入到request作用域
//request.setAttribute("msg","欢迎使用springmvc做web开发");
//数据放到Redirect作用域
mv.addObject("myname",name);
mv.addObject("myage",age);
//显示重定向
//mv.setViewName("forward:/WEB-INF/view/show.jsp");
mv.setViewName("redirect:/hello.jsp");
//返回mv
return mv;
}
}
异常处理
自定义异常类
package com.gy.exception;
public class MyUserException extends Exception{
public MyUserException() {
super();
}
public MyUserException(String message) {
super(message);
}
}
package com.gy.exception;
//表示当用户的姓名有异常,抛出NameException
public class NameException extends MyUserException{
public NameException() {
super();
}
public NameException(String message) {
super(message);
}
}
package com.gy.exception;
//表示当用户的年龄有异常,抛出AgeException
public class AgeException extends MyUserException{
public AgeException() {
super();
}
public AgeException(String message) {
super(message);
}
}
全局普通异常类
package com.gy.handler;
import com.gy.exception.AgeException;
import com.gy.exception.NameException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
* @ControllerAdvice: 控制器增强(也就是说给控制器类增加功能--异常处理功能)
* 位置:在类的上面
* 特点:必须让框架知道这个注解所在的包名,需要在springmvc配置文件声明组件扫描器
* 指定@ControllerAdvice所在的包名
*/
@ControllerAdvice
public class GlobalExceptionHandler {
//定义方法,处理发生的异常
/**
* 处理异常的方法和控制器方法的定义一样,可以有多个参数,可以有ModelAndView;
* string,void,对象类型的返回值
*
* 形参:Exception,表示controller中抛出的异常对象
* 通过形参可以获取发生的异常信息
*
* @ExceptionHandler(异常的class):表示异常的类型,当发生此类型异常时,
* 有此方法处理
* */
@ExceptionHandler(value = NameException.class)
public ModelAndView doNameException(Exception exception){
//处理NameException的异常
/*
* 异常发生处理逻辑
* 1.需要把异常记录下来,记录到数据库,日志文件
* 记录日志发生的时间,哪个方法发生的,异常错误类型
* 2.发送通知,把异常的信息通过邮件.短信.微信发送给相关人员
* 3.给用户友好的提示
* */
ModelAndView mv=new ModelAndView();
mv.addObject("msg","姓名必须是zs,其他用户不能访问");
mv.addObject("ex",exception);
mv.setViewName("nameError");
return mv;
}
//处理age异常
@ExceptionHandler(value = AgeException.class)
public ModelAndView doAgeException(Exception exception){
//处理AgeException的异常
/*
* 异常发生处理逻辑
* 1.需要把异常记录下来,记录到数据库,日志文件
* 记录日志发生的时间,哪个方法发生的,异常错误类型
* 2.发送通知,把异常的信息通过邮件.短信.微信发送给相关人员
* 3.给用户友好的提示
* */
ModelAndView mv=new ModelAndView();
mv.addObject("msg","年龄不能大于90");
mv.addObject("ex",exception);
mv.setViewName("ageError");
return mv;
}
//处理其他异常AgeException,和NameException以外的,
@ExceptionHandler
public ModelAndView doOtherException(Exception exception){
//处理其他异常
ModelAndView mv=new ModelAndView();
mv.addObject("msg","意外异常");
mv.addObject("ex",exception);
mv.setViewName("otherError");
return mv;
}
}
异常处理配置文件springmvc
<!--处理异常需要两步-->
<context:component-scan base-package="com.gy.handler"/>
<mvc:annotation-driven/>
拦截器
定义接口
package com.gy.handler;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//拦截器类:拦截用户的请求
public class MyInterceptor implements HandlerInterceptor {
/**
* preHandle叫做预处理方法
* 重要:是整个项目的入口,门户,当preHandler返回true 请求可以被处理
* preHandler返回false 请求到此方法就截止
* 参数:
* object handler :被拦截的控制器对象
* 返回值Boolean
* true:请求时通过了拦截器的验证,可以执行处理器方法.
* 拦截器的MyInterceptor的preHandle()
* ===========
* 拦截器的MyInterceptor的postHandle()
* 拦截器的MyInterceptor的afterCompletion()
* false:请求时没有通过拦截器的验证,请求到达拦截器就截止了,请求没有被处理.
* 拦截器的MyInterceptor的preHandle()
* 特点:
* 1.方法在控制器方法(Mycontroller的doSome)之前先执行
* 用户的请求首先到达此方法
* 2.在这个 方法中可以获取请求的信息,验证请求是否符合要求
* 可以用户是否登录,验证用户是否有权限访问某个链接地址(url)
* 如果验证失败,可以截断请求,请求不能被处理
* 如果验证成功,可以发行请求,此时控制器方法才能执行
*
*
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("拦截器的MyInterceptor的preHandle()");
//计算的业务逻辑,根据计算结果,返回true还是false
//给浏览器一个返回结果
request.getRequestDispatcher("/tips.jsp").forward(request,response);
return false;
}
/**
* postHandle叫做后处理方法
* 参数:
* object handler :被拦截的控制器对象Mycontroller
* ModelAndView mv:处理器方法的返回值
* 特点:
* 1.方法在控制器方法(Mycontroller的doSome)之后先执行
*
* 2.能够获取到处理器方法的返回值ModelAndView,可以修改ModelAndView中的数据和视图
* 可以影响到最后的执行效果
* 3.主要是对原来的执行结果做二次修正
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器的MyInterceptor的postHandle()");
}
/**
* afterCompletion叫做后处理方法
* 参数:
* object handler :被拦截的控制器对象Mycontroller
* Exception ex是程序中发生的异常
* 特点:
* 1.在请求处理完成后执行的,框架中规定是当你的视图处理完成后,
* 对视图执行了forward,就认为请求处理完成
* 2.一般做资源回收工作,程序请求过程中创建了一些对象,在这里可以删除,把占用的内存回收
*
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("拦截器的MyInterceptor的afterCompletion()");
}
}
多个拦截器的执行顺序