Spring Web中拦截器(Interceptor)和控制器(Controller)各自应该有什么功能?
我个人的习惯是拦截器检查用户请求是否正确。如果用户请求正确,则把请求交给控制器处理;如果请求不正确,则给用户返回错误信息。也就是说拦截器处理错误情况,控制器处理正常情况。但有时拦截器似乎越俎代庖做了控制器应该做的事情。
例如下面的例子。数据库中共有100篇文章,每页列表有10篇,共有10页文章列表。如果用户请求第1至10页文章列表,这属于正常情况,应该而且可以在控制器中处理,控制器从数据库中读取文章列表,拦截器只需要检查用户的页码参数是否正确。如果用户请求第11页文章列表,显然该页不存在。我认为这种错误情况应该在拦截器中处理,给用户返回404 页面。为了处理错误情况和减少数据库读写次数,读取文章总数和文章详情的操作都在拦截器中一次完成。
那么读取文章列表的操作应该在拦截器还是控制器中执行呢?
还有几种情况需要与向各位请教。
情况一。用户访问特定文章的详情页面,请求内包含文章id。是否需要在拦截器内检查该id对应的文章是否存在(该操作需要查询数据库)?如果是在控制器进行检查,如果用户请求的文章不存在,该如何在控制器内处理错误?
情况二。用户从服务器获取编辑文章的页面或向服务器提交删除文章的请求,该两种请求中都包含文章id。判断用户是不是文章的作者需要读取数据库,如果用户不是作者,则返回403页面。这一操作应该在拦截器中还是控制器中?
情况三。用户向服务器提交对文章的修改,该请求中包含文章id、文章标题和内容。有两点需要判断。第一,用户是不是文章的作者。这不是这一问题关注的重点。第二,判断用户提交的新文章与数据库中的内容是否相同,如果相同,则给用户返回304(未改变)状态码,这需要读取数据库。校验文章内容是否改变这一操作应该在拦截器中还是控制器中执行呢?
回答
你的拦截器做的功能是不是过多了,拦截器的主要职责不是校验请求是否合法吗?比如说校验这个请求的地址是不是合法的,请求是否携带某些必备的信息等等,应该是一种通用的在请求之前的处理。
控制器只接受合法的请求,并对合法的请求中携带的参数进行校验、处理,然后调用service层,然后再返回。