回顾
springmvc
1,入门案例
-
引入坐标
spring相关、spring-web、spring-webmvc
-
配置web.xml
前端控制器:是一个servlet。指定springmvc的配置文件的路径
-
springmvc配置
组件扫描
<!--扫描加载所有的控制类--> <context:component-scan base-package="com.itheima.controller"/>
-
编写代码
@Controller @RequestMapping("/user") public class UserController { @RequestMapping("/save") public String save() { return "index.jsp"; } }
2,静态资源处理
方式1:
<mvc:resources mapping="/img/**" location="/img/"></mvc:resources>
<mvc:annotation-driven/>
方式2:将静态资源处理交给tomcat提供的DefaultServlet
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
3,请求
3.1 请求数据(重点)
-
普通类型的数据
在controller方法上声明和请求参数名相同的参数名
-
pojo类型的数据
在controller方法上声明pojo类型的数据(User user),请求参数名和pojo的属性名保持一致。
-
集合类型的数据
在controller方法上声明集合类型(@RequstParam(“参数名”) List ids),
3.2 请求映射
@RequestMapping
使用类上或者方法上
value属性: 请求的资源路径
method属性: 限制请求的方式
今日内容
- 响应
- ajax请求
- 拦截器
- 异常处理器
- 文件上传 fileupload
1,响应
1.1 视图是jsp
1.1.1 资源跳转
controller方法的返回表示资源跳转。返回值是资源的路径
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save")
public String save() {
return "/index.jsp";
}
}
默认使用的是转发。可以修改为重定向吗? 可以
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save")
public String save() {
return "redirect:/index.jsp";
}
}
配置视图解析器,并指定前缀和后缀:
默认会加载视图解析器,但是没有配置前缀和后缀,如果需要配置前缀和后缀,就需要手动配置视图解析器:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
controller方法的写法:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save")
public String save() {
return "index"; // /WEB-INF/page/index.jsp
}
}
1.1.2 携带数据
-
使用原生的API(了解)
@RequestMapping("/showPage") public String showPage(HttpServletRequest request) { request.setAttribute("username","robin"); return "page.jsp"; }
-
使用Model
model : 模型。用来封装,并将封装好的数据存储到request域对象中。
@RequestMapping("/showPage") public String showPage(Model model) { model.addAttribute("username","robin"); return "page.jsp"; }
-
使用ModelAndView
ModelAndView:
model : 模型。用来封装,并将封装好的数据存储到request域对象中。
view : 视图,页面资源的路径。
@RequestMapping("/showPage") public ModelAndView showPage(ModelAndView modelAndView) { modelAndView.addObject("username","robin"); modelAndView.setViewName("index.jsp"); return modelAndView; }
1.2 视图是html
需要响应的数据是json。
要想响应json数据,要使用@ResponseBody,将controller方法的返回值直接响应回给浏览器。
@RequestMapping("/showData4")
@ResponseBody
public Book showData4() {
Book book = new Book();
book.setName("SpringMVC入门案例");
book.setPrice(66.66d);
return book; //会将对象转换为json进行响应,默认使用的是jackson
}
//转换集合类型数据
@RequestMapping("/showData5")
@ResponseBody
public List showData5() {
Book book1 = new Book();
book1.setName("SpringMVC入门案例");
book1.setPrice(66.66d);
Book book2 = new Book();
book2.setName("SpringMVC入门案例");
book2.setPrice(66.66d);
ArrayList al = new ArrayList();
al.add(book1);
al.add(book2);
return al;
}
注意:
需要导入jackson包
<!--json相关坐标3个-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
需要配置注解驱动
<mvc:annotation-driven/>
小扩展:
我们发现了问题,每一个方法都需要添加@ResponseBody,能不能简化?能将@ResponseBody加到类上
@Controller
@ResponseBody
public class AccountController {
//使用SpringMVC注解驱动,对标注@ResponseBody注解的控制器方法进行结果转换,由于返回值为引用类型,自动调用jackson提供的类型转换器进行格式转换
@RequestMapping("/showData4")
//@ResponseBody
public Book showData4() {
Book book = new Book();
book.setName("SpringMVC入门案例");
book.setPrice(66.66d);
return book;
}
//转换集合类型数据
@RequestMapping("/showData5")
//@ResponseBody
public List showData5() {
Book book1 = new Book();
book1.setName("SpringMVC入门案例");
book1.setPrice(66.66d);
Book book2 = new Book();
book2.setName("SpringMVC入门案例");
book2.setPrice(66.66d);
ArrayList al = new ArrayList();
al.add(book1);
al.add(book2);
return al;
}
}
再次优化:将@Controller注解和@ResponseBody合并成一个注解 @RestController。
2,原生API的替换(了解)
@RequestHeader --> request.getHeader(...)
@CookieValue --> request.getCookies()
@SessionAttribute --> request.getSession().getAttribute(...)
@SessionAttributes : 指定将数据存储到session域对象的变量名
登陆状态校验:
@SessionAttribute
@SessionAttributes
文件下载:
@RequestHeader
3,@RequestBody
使用ajax请求的话,我们可以使用@RequestBody 进行数据的封装。
4,跨域
三个维度:
ip地址|域名
端口号
协议
三个维度中只要有一个不一样就是跨域
http://localhost/a.jsp
https://localhost/getData
http://localhost/a.jsp
http://localhost:8080/getData
http://localhost/a.jsp
http://www.robin.com/getData
http://localhost/a.jsp
http://localhost/getData ---> 不属于跨域
如果实现跨域访问?
方式1:(了解)
response.setHeader("Access-Control-Allow-Origin","*");
方式2:(掌握)
@CrossOrigin 该注解放在类上,说明类中所有的资源都可以跨域访问,放在方法上,该方法可以实现跨域访问
注意: 下来自己联系,一定记住修改hosts文件
www.robin.com 127.0.0.1
5,拦截器
5.1 概述:
一种动态增强处理器方法的机制。
过滤器和拦截器的区别:
- 过滤器可以拦截所有的资源
- 拦截器只能拦截处理器
- 过滤器是servlet提供的技术
- 拦截器是springmvc提供的
5.2 自定义拦截器
定义拦截器类
public class MyInterceptor implements HandlerInterceptor {
//处理器运行之前执行
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("前置运行----a1");
return true;//返回值是true,表明放行,返回的是false,结束
}
//处理器运行之后执行
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("后置运行----b1");
}
//所有拦截器的后置执行全部结束后,执行该操作
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("完成运行----c1");
}
}
配置
<mvc:interceptors>
<!--开启具体的拦截器的使用,可以配置多个-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!--指定具体的拦截器类-->
<bean class="com.itheima.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
5.3 配置
<mvc:mapping/> 用来配置拦截的路径
/* : 只拦截单级路径 /save /update
/** : 拦截所有的handler路径 /save /update /user/save
一般开发中使用 /**
<mvc:interceptors>
<!--开启具体的拦截器的使用,可以配置多个-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!--指定具体的拦截器类-->
<bean class="com.itheima.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
6,异常处理
6.1 自定义异常处理 (了解)
规范: 实现 HandlerExceptionResolver
@Component
public class MyExcpetionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
System.out.println(ex);
ModelAndView mv = new ModelAndView();
mv.addObject("message","对不起,系统繁忙, 请稍后重试");
mv.setViewName("error.jsp");
return mv;
}
}
6.2 注解开发(掌握)
@ControllerAdvice
public class ExceptionAdvice {
//类中定义的方法携带@ExceptionHandler注解的会被作为异常处理器,后面添加实际处理的异常类型
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public String doNullException(Exception ex){
return "空指针异常";
}
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public String doArithmeticException(Exception ex){
return "ArithmeticException";
}
@ExceptionHandler(Exception.class)
@ResponseBody
public String doException(Exception ex){
return "all";
}
}
小结:
-
响应
- 跳转页面
- 使用Model对象存入数据(默认存储在request域对象中)
- 跳转
- controller方法的返回值
- 使用ModelAndView对象
- 直接响应数据
- @ResponseBody : 直接响应数据
- 响应json数据
- 返回对象或者集合,springmvc会默认使用jackson工具转换为json数据进行响应
- 跳转页面
-
ajax请求的请求数据的封装
- @RequestBody
-
跨域问题
-
拦截器
- 自定义拦截器
-
异常处理器
-
异常
- @ControllerAdvice
lic String doException(Exception ex){
return “all”;
}
}
- @ControllerAdvice