spring mvc 拦截ajax请求参数值,SpringMVC框架(DispatcherServelt、请求参数处理、异常处理、拦截器)...

文章目录

SpringMVC框架介绍

Springmvc架构原理解析

SpringMVC配置DispatcherServlet中央调度器

@Controller注解

@RequestMapping注解

控制器方法请求参数获取

逐个参数接收

CharacterEncodingFilter解决中文乱码

控制器方法返回值

String 返回值(跳转页面)

ModelAndView 返回值(域对象)

void 返回值(Ajax响应)

Object 返回值(注解Ajax响应)

注解Ajax响应文本

中央调度器 ``

如何解决访问静态资源

异常处理

拦截器

什么是拦截器

拦截器的执行

拦截器的使用

多个拦截器的执行

拦截器与过滤去的区别

SpringMVC框架介绍

springmvc是一个基于mvc的web框架。

springmvc拥有控制器,作用跟Struts类似,用于接收外部请求,解析参数传给服务层。

MVC是指 Model(模型)、View(视图)、Controller(控制器)的简写。

MVC主要的作用是降低了视图与业务逻辑的双向耦合。

Springmvc架构原理解析

ae92b8df8455853d5ad8d96ff69e713d.png

发起请求到中央调度器 DispatcherServlet。

中央调度器接收到请求后,调用 HandlerMapping 映射器查找 Handler。

HandlerMapping 映射器根据xml配置、注解进行查找具体的处理器 Handler,生成处理器对象及连接器一并向中央调度器返回 Handler。

中央调度器调用 HandlerAdapter 设配器执行Handler。

HandlerAdapter 适配器经过适配调用具体的处理器(Controller 也称:控制器)进行业务逻辑操作。

Handler执行完成给适配器返回ModelAndView。

HandlerAdapter 将 Handler 执行结果 ModelAndView 返回给中央调度器(ModelAndView是springmvc框架的一个底层对象,包括 Model和view)。

中央调度器将 ModelAndView 传给 ViewResolver 视图解析器进行视图解析,根据逻辑视图名解析成真正的视图(jsp)。

ViewResolver 视图解析器向中央调度器返回View。

中央调度器进行视图渲染,视图渲染将模型数据(在ModelAndView对象中)填充到request域。

前端控制器向用户响应结果。

前端控制器 DispatcherServlet(不需要程序员开发)

作用:接收请求,响应结果,相当于转发器,中央处理器。有了DispatcherServlet减少了其它组件之间的耦合度。

处理器映射器 HandlerMapping(不需要程序员开发)

作用:根据请求的url查找Handler。

处理器适配器 HandlerAdapter

作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler。

处理器 Handler(需要程序员开发)

注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。

视图解析器 ViewResolver(不需要程序员开发)

作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)

视图View(需要程序员开发jsp) View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)

SpringMVC配置DispatcherServlet中央调度器

在pom.xml中加入servlet-api和springmvc依赖。

javax.servlet

javax.servlet-api

3.1.0

provided

org.springframework

spring-webmvc

5.2.5.RELEASE

在Web.xml配置文件中注册SpringMVC框架的核心对象 DispatcherServlet,用设置spring配置文件。(注意此处的web-app版本是4.0) <?xml version="1.0" encoding="UTF-8"?>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"

version="4.0">

springmvc

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath:applicationContext.xml

1

springmvc

*.do

在resources文件中创建spring配置文件applicationContext.xml。设置视图解析器用于处理不公开的jsp文件。

@Controller注解

1)创建一个MyController类并使用@Controller注解标识此类为控制器对象。

@Controller

public class MyController {

@RequestMapping("/doSome.do")

public ModelAndView doSome() {

ModelAndView modelAndView = new ModelAndView();

modelAndView.addObject("msg","smg数据");

modelAndView.setViewName("show");

return modelAndView;

}

}

@RequestMapping注解

在类上定义注解称父级接口。 @RequestMapping("/test")

public class MyController {

}

在方法上定义注解称子级级接口。 @RequestMapping(value = "/doSome.do")

public ModelAndView doSome() {

}

接口访问方式:http://xxxx.xxxx/test/doSome.do

在注解中定义请求方式,method属性表示请求方式,它的值是RequestMethod类枚举值。 @RequestMapping(value = "/doSome.do",method = RequestMethod.GET)

public class MyController {

}

控制器方法请求参数获取

被@RequestMapping注解所表示的方法有三种参数:请求、响应、会话。这些参数在系统被调用时由系统自动赋值。 @RequestMapping(value = "/doSome.do",method = RequestMethod.GET)

public ModelAndView doSome(HttpServletRequest res, HttpServletResponse resp,HttpSession seion) {

}

逐个参数接收

接收用户提交的参数与控制器方法的形参名保持一直。

@RequestMapping(value = "/login.do",method = RequestMethod.POST)

public ModelAndView otherSome(String username,String password) {

}

CharacterEncodingFilter解决中文乱码

在web.xml配置文件中注册过滤器,过滤所有接口解决中文乱码。

characterEncodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

forceRequestEncoding

true

forceResponseEncoding

true

characterEncodingFilter

/*

控制器方法返回值

String 返回值(跳转页面)

直接return 要跳转页面的名称,框架会用视图解析器作拼接。

数据的返回可以在形参中加入 HttpServletRequest 对象,并设置对象域在页面接收即可。

@RequestMapping(value = "/returnString-view.do",method = RequestMethod.POST)

public String doReturnStringView(HttpServletRequest req,String username, String password) {

req.setAttribute("username",username);

req.setAttribute("password",password);

return "show";

}

ModelAndView 返回值(域对象)

@RequestMapping注解:可以设置在方法上或是一个类中。

@RequestMapping注解:请求映射,作用是把请求地址与方法绑定,一个请求指定一个方法处理。

@RequestMapping注解:被修饰的方法叫做处理器方法或者控制器方法可以处理请求,类似servlet中的doGet、doPost。

ModelAndView对象:

addObject(String attributeName, @Nullable Object attributeValue):添加数据,框架在请求的最后把数据放入到request作用域中。

setViewName(@Nullable String viewName):指定视图,框架对视图执行request.getRequestDispatcher("/show.jsp").forward(req,resp)操作。

参数:框架会使用视图解析器拼接路径:前缀 + 文件名 + 后缀。 @RequestMapping(value = "/returnObject-view.do",method = RequestMethod.POST)

public ModelAndView doReturnObjectView(String username, String password) {

ModelAndView modelAndView = new ModelAndView();

Student student = new Student();

student.setUsername(username);

student.setPassword(password);

modelAndView.addObject(student);

modelAndView.setViewName("show");

return modelAndView;

}

void 返回值(Ajax响应)

在处理 Ajax 的时候,可以使用 void 返回值。

Ajax 请求服务器端放回的就是数据和视图无关。

使用 HttpServletResponse 输出数据响应Ajax请求,Ajax 请求所接受的数据个格式为 JSON,需要使用 Jackson 依赖使对象转换为 JOSN 字符串,而 Ajax 会把 JOSN 字符串解析为 JSON。

@RequestMapping(value = "/returnVoid-ajax.do")

public void doReturnAjax(HttpServletResponse resp, String username, String password) throws IOException {

Student student = new Student();

student.setUsername(username);

student.setPassword(password);

//对象转换为json结果

String json = null;

if (student != null) {

ObjectMapper objectMapper = new ObjectMapper();

json = objectMapper.writeValueAsString(student);

System.out.println(json);

}

//响应ajax请求

resp.setContentType("application/json; charset=utf-8");

resp.getWriter().write(json);

}

$(function(){

$("#btn").click(function() {

$.post("user/returnVoid-ajax.do",{username:"tuoyingtao",password:"123456"},

function fun(response) {

alert(JSON.stringify(response))

},"json")

})

})

Object 返回值(注解Ajax响应)

springmvc 控制器方法返回 Object,转换 JSON 输出到浏览器,响应原理:

1)注解驱动:完成 Java 对象到 JOSN、xml、text、二进制等数据格式的转换。

2)在加入到 springmvc 配置后会自动创建 HttpMessageConverter 接口的实现类,包括 MappingJackson2HttpMessageConverter。 (内部使用 Jackson 工具库中的 ObjectMapper 实现 Java 对象转为 JSON 字符串)

3)HttpMessageConverter 接口两个方法:

canWrite(Class> clazz, @Nullable MediaType mediaType);:检查控制器方法返回值,是否可与转换为 mediaType 的数据格式。

write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage):把控制器方法的放回对象,掉用 Jackson 中的 ObjectMapper 转为 JSON 格式。

4)调用@ResponseBody吧数据结果输出到浏览器,ajax处理响应。

把处理器返回对象转换为JSON后,通过 HttpServletResponse 输出给浏览器。

第一步引入 Jackson 依赖:

com.fasterxml.jackson.core

jackson-core

2.9.0

com.fasterxml.jackson.core

jackson-databind

2.9.0

第二步 在spring配置文件注册 annotation-driver 驱动:(注意:包路径是mvc下的)

第三步 使用 @ResponseBody 注解将数据响应给 Ajax 请求:

//返回对象

@ResponseBody

@RequestMapping(value = "/returnStudentJson.do",method = RequestMethod.POST)

public Student doReturnStudentJson(String username, String password) {

Student student = new Student();

student.setUsername("托马斯·克里斯特");

student.setPassword("123456");

return student;

}

//返回List数组

@ResponseBody

@RequestMapping(value = "/returnStudentList.do",method = RequestMethod.POST)

public List doReturnStudentList(String username, String password) {

List list = new ArrayList();

Student student = new Student();

student.setUsername("托马斯·克里斯特");

student.setPassword("123456");

Student student1 = new Student();

student1.setUsername("玛丽·莫利亚");

student1.setPassword("123456");

list.add(student);

list.add(student1);

return list;

}

注解Ajax响应文本

1)控制器方法返回String的数据,不是视图。

2)如果加上@ResponseBody注解,则表示返回的就是文本数据,反之就是视图。

3)返回文本数据时默认使用 text/plain;charset=ISO-8859-1 作为ContentType,导致中文乱码。

解决:在 @RequestMapping 中添加 produces 属性来指定ContentType类型。

@ResponseBody

@RequestMapping(value = "/returnStringData.do",produces = "text/plain;charset=utf-8")

public String doStringData(String username,String password) {

return "杰克·罗伯塔";

}

中央调度器

在没有特殊要求的情况下,springmvc 的中央调度器 DispatcherServlet 的< url-pattern/ >常使用后缀匹配方式,如写为 *.do 或者 *.action , *.mvc 等。

也可以使用/代替。当我们发起静态资源请求时,DispatcherServelt 会将此请求最为普通的 Controller。中央调度器会调用控制器映射器为其查找相应的控制器。在这种情况下所有静态资源请求会报错404。

一般服务器所返回的静态资源都是由 Tomcat 自身处理的。

Tomcat的 web.xml 配置文件里有一个名为 default 的servelt,当运行 Tomcat 时会创建 DefaultServlet 对象,用于处理静态资源与为映射的请求。

default

org.apache.catalina.servlets.DefaultServlet

debug

0

listings

false

1

default

/

如何解决访问静态资源

1)第一种:在 springmvc 配置文件里加入标签:框架创建控制器对象,把接受到的请求转发给 Tomcat。

2)第二种:在 springmvc 配置文件里加入标签:框架创建 ResourceHttpRequestHandler 控制器对象,让这个对象处理静态资源的访问,不依赖 Tomcat 服务器。

location 属性:静态资源在你的项目中的目录位置。

mapping 属性:访问静态资源的 URL 地址,使用通配符 **。

3d8086782ab1cdd86e0c770913f62144.png

异常处理

springmvc 框架采用的是统一,全局的异常处理。把 controller 中的所有异常处理都集中到一个地方,采用aop思想,把业务逻辑和异常处理代码分开。也称解耦合。

使用两个注解:

ControllerAdvice:控制器增强 ,必须让框架知道这个注解所在的包名,需要在springmvc配置文件声明 组件扫描器 指定 @ControllerAdvice 所在的全局异常处理类包名。

ExceptionHandler:表示异常的类型,当发生此类型的异常时,由当前方法处理。处理异常的方法和控制器方法的定义一样,可以有多个参数。可以有ModelAndView,String,void对象类型的返回值, 形参:Exception,表示Controller中抛出的异常对象,通过形参可以获取发送的异常信息。

8b044fe8d978a3c84570d0ca080cb1c3.png

1)自定义异常类 MyUserException.java,继承 Exception类。

public class MyUserException extends Exception{

public MyUserException() {

super();

}

public MyUserException(String message) {

super(message);

}

}

2)创建 MyUserException 的子类 NameException.java、PasswordException.java。

public class UsernameException extends MyUserException{

public UsernameException() {

super();

}

public UsernameException(String message) {

super(message);

}

}

public class PasswordException extends MyUserException {

public PasswordException() {

super();

}

public PasswordException(String message) {

super(message);

}

}

3)在控制器方法中,捕获NameException、PasswordException异常,并抛出父类异常 MyUserException。

@Controller

public class MyController {

@ResponseBody

@RequestMapping(value = "/errorData",method = RequestMethod.POST)

public ModelAndView doErrorData(String username,String password) throws MyUserException {

System.out.println(username + password);

ModelAndView mv = new ModelAndView();

//更具请求参数抛出异常

if (!"托马斯·克里斯特".equals(username)) {

throw new UsernameException("姓名有误!!!");

}

if (!"123456".equals(password)) {

throw new PasswordException("密码有误!!!");

}

mv.addObject("username",username);

mv.addObject("password",password);

mv.setViewName("show");

return mv;

}

}

4)创建 GlobalExceptionHandler 类,作为 全局异常处理类。

@ControllerAdvice

public class GlobalExceptionHandler {

//定义处理异常方法

@ExceptionHandler(value = UsernameException.class)

public ModelAndView doUsernameException(Exception e) {

//处理账号异常

ModelAndView mv = new ModelAndView();

mv.addObject("message","姓名必须为托马斯·克里斯特!!!");

mv.addObject("error",e);

mv.setViewName("uesrnameError");

return mv;

}

@ExceptionHandler(value = PasswordException.class)

public ModelAndView doPasswordException(Exception e) {

//处理账号异常

ModelAndView mv = new ModelAndView();

mv.addObject("message","密码必须为123456!!!");

mv.addObject("error",e);

mv.setViewName("passwordError");

return mv;

}

//处理未知异常

@ExceptionHandler

public ModelAndView doOtherException(Exception e) {

ModelAndView mv= new ModelAndView();

mv.addObject("message","用户或密码错误我!");

mv.addObject("error",e);

mv.setViewName("defaultError");

return mv;

}

}

5)springmvc 配置文件扫描异常处理程序与注册驱动。

拦截器

什么是拦截器

1)拦截器是 springmvc 中的一种,需要实现 HandlerInterceptor 接口。

2)拦截器与过滤器类似,处理的应用场景不同。过滤器是用来过滤请求参数,设置字符集编码等,而拦截器则是对用户的请求做拦截,对请求做判断处理。

3)拦截器是全局的,可以对多个 Controller 做拦截。一个项目可以有多个拦截器。常用在:用户登录处理、权限检查、记录日志等。

拦截器的执行

定义一个拦截器类实现 HandlerInterceptor 接口,重写以下三个方法:preHandle()、postHandle()、afterCompletion()。

1)preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler):在请求处理之前,也就是 Controller 类中的方法之前先被拦截,如果返回值为 true 就继续执行下一步,如果为 false 就终止,在这个方法中可以获取用户请求信息,验证请求是否符合要求。

2)preHandle()返回 true 执行 Controller 类中的方法。

3)postHandle(HttpServletRequest req, HttpServletResponse resp, Object handler, ModelAndView mv):在控制器方法执行之后执行拦截器,能够获取控制器方法的返回值 ModelAndView,可以修改 ModelAndView中的数据和视图,可以影响最后的执行结果,主要对原来的执行结果做二次修改。

4)afterCompletion(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex):在请求处理完后执行拦截器,在框架中规定是当你的视图处理完成后,对视图执行了 forward,就认为请求处理完成,一般做资源回收工作的,程序请求过程中创建了一些对象,在这里可以删除,把占用的内存回收。。

拦截器的使用

定义类实现 HandlerInterceptor 接口。 public class MyInterceptor implements HandlerInterceptor {

/**

* @param request

* @param response

* @param handler 被拦截的控制器对象

* @return Boolean

* @throws Exception

*/

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("拦截器MyInterceptor的preHandle方法");

return true;

}

/**

* @param request

* @param response

* @param handler 被拦截的控制器对象

* @param modelAndView 处理器方法的返回值

* @throws Exception

*/

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

System.out.println("拦截器MyInterceptor的postHandle方法");

}

/**

* @param request

* @param response

* @param handler 被拦截的控制器对象

* @param ex 程序中发生的异常

* @throws Exception

*/

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

System.out.println("拦截器MyInterceptor的afterCompletion方法");

}

}

在 springmvc 配置文件中声明拦截器,在框架中多个拦截器是按照顺序存放到 ArrayList 中的。

执行顺序

66770d40046ffb8851a643b8d0e0a193.png

多个拦截器的执行

1)MyInterceptor 拦截器类一

public class MyInterceptor implements HandlerInterceptor {

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("拦截器MyInterceptor的preHandle方法");

return true;

}

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

System.out.println("拦截器MyInterceptor的postHandle方法");

}

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

System.out.println("拦截器MyInterceptor的afterCompletion方法");

}

}

2)MyInterceptor2拦截器类二

public class MyInterceptor2 implements HandlerInterceptor {

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("拦截器MyInterceptor的preHandle方法22222222");

return true;

}

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

System.out.println("拦截器MyInterceptor的postHandle方法2222222222");

}

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

System.out.println("拦截器MyInterceptor的afterCompletion方法2222222");

}

}

3)springmvc 配置文件

情况一:当 MyInterceptor 和 MyInterceptor 2 拦截器中的 preHandle() 返回 都为 true 时执行结果。

2ea2613c0605af57deff0bfe9454aed4.png

情况二:当 MyInterceptor2 拦截器中的 preHandle() 返回 false 时执行结果。

b68ac1289d284d8b920c4d1b705924b4.png

情况三:当 MyInterceptor 拦截器中的 preHandle() 返回 false 时执行结果。

f6153faff184b2e490dce47bcce123a4.png

拦截器与过滤去的区别

过滤器是 servlet 中的对象。

拦截器是框架中的对象。

过滤器是实现 Filte 接口的对象。

拦截器是实现 Handlerinterceptor 接口。

过滤器是用来设置 request、response 的参数,是对数据的过滤。

拦截器是用来验证请求的,能截断请求。

过滤器是在拦截器之前先执行的。

拦截器是 springmvc 容器中的对象。

过滤器是一个执行时间点。

拦截器有三个执行时间点。

过滤器可以处理 jsp、js、html 等。

拦截器是对 Controller 的对象拦截,如果你的请求不能被 DispatcherServlet 接受,这个请求不会执行拦截器。

过滤器过滤 servlet 请求响应。

拦截器拦截普通方法的执行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值