目录
一.Spring web的认识
(1)Spring Web概念
SpringWeb 是 spring 框架中的一个模块,基于 Servlet API 构建的 web 框架. springWeb 是 Spring 为 web 层开发提供的一整套完备的解决方案。 在 web 层框架历经 Strust1,WebWork,Strust2 等诸多产品的历代更选之后, 目前业界普遍选择了 springWeb 作为 Java EE 项目 web 层开发的首选方案。(与原生的servlet相比,不需要我们在创建多个servlet程序,Spring web只有一个Servlet)
(2)Spring web的特点
(1)SpringWEB 是 spring 家族原生产品,与 IOC 容器等基础设施无缝对接.(2) 基于原生的 Servlet,提供了一个前端控制器 DispatcherServlet ,开发者(3)无须额外开发控制器对象.(4)可以自动绑定用户输入,并正确地转换数据类型.(5)代码清新简洁,大幅度提升开发效率.(6)内部组件化程度高,可插拔式组件即插即用.(7)性能卓著,尤其适合现代大型、超大型互联网项目要求.
(3)Springweb运行的流程
(1)用户发送出请求到前端控制器 DispatcherServlet。(2)DispatcherServlet 收到请求调用 HandlerMapping(处理器映射器)。(3)HandlerMapping 找到具体的处理器(可查找 xml 配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给 DispatcherServlet。(4) DispatcherServlet 调用 HandlerAdapter(处理器适配器)。(5)HandlerAdapter 经过适配调用具体的处理器(Handler/Controller)。(6)Controller 执行完成向前端响应结果。
(4)Springweb运行的流程图
注意Springweb只有一个servlet,每次启动服务器时都会自动创建一个servlet对象,并且我们需要写的只有一个自定义处理器和拦截器,其他的都由Spring 框架帮我们实现。
二.搭建Spring web
第一步:导包,在pom.xml中导入Spring web相关的包。
第二步:在web.xml文件中配置DispatcherServlet。
第三步:开启 springweb 注解。
Spring web相关的jar包
< dependency >< groupId >org.springframework</ groupId >< artifactId >spring-webmvc</ artifactId >< version >5.2.2.RELEASE</ version ></ dependency >
在 web.xml 文件中对DispatcherServlet的相关配置
< servlet >< servlet-name >application</ servlet-name >< servlet-class >org.springframework.web.servlet.DispatcherServlet</ servlet-class >< init-param >< param-name >contextConfigLocation</ param-name >< param-value >classpath:spring.xml</ param-value ></ init-param >< load-on-startup >0</ load-on-startup ></ servlet ><!-- 请求映射 -->< servlet-mapping >< servlet-name >application</ servlet-name >< url-pattern >/</ url-pattern ></ servlet-mapping >
开启 springweb 注解< mvc :annotation-driven ></ mvc :annotation-driven >
三.自定义处理器类搭建
(1)处理器类配置
@RestController 用于标记在一个类上,使用它标记的类就是一个 SpringWEB 控制器类(也就是我们原先在原始的servlet中写的servlet类).
Spring 配置中指定了自动扫描的 basepackage 后,Spring 会扫描这些包以及子包中的使用了@RestController 标识的类,然后将类加入到 Spring IOC 容器 中,注入依赖。 @RequestMapping 注解是一个用来处理请求地址映射的注解,可用于类或方法上。(用于为该类定义类的地址和该类方法的地址,通过这两个地址就能直接找到方法,不用再用原生的servlet使用mark进行判断)
如图:
(2)处理器类接受请求
常用属性 path,value,method.path 和 value 用来定义地址method 用来定义请求方式@RequestMapping(value = "/hello",method = RequestMethod.GET)@RequestMapping(path= "/hello",method = RequestMethod.POST)
(3)获得请求数据
//前端和后端交互第一种方式:原生的Httpservlet方式
@PostMapping(path = "/login")
public String login(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
System.out.println(httpServletRequest.getParameter("account"));
System.out.println(httpServletRequest.getParameter("password"));
System.out.println(httpServletRequest.getRemoteAddr());
System.out.println("登录");
return "success";
}
2.使用参数进行请求
//前端和后端交互第二种方式:通过参数发送
//@RequestParam("account")是用来给方法的参数进行起名,防止方法中的参数与客户端的参数名不一致
@PostMapping(path = "/login")
public String login(@RequestParam("account") String account1,@RequestParam("password") String password1){
System.out.println("登录");
return "success";
}
3.使用对象接受请求
@PostMapping(path = "/login")
//*
//@RequestBody说明前端传过来的对象是Jsong格式的对象
public Result login(@RequestBody Admin admin){
Admin admin1= loginservice.login(admin);
Result result=new Result(200,"登陆成功",admin1);
System.out.println("登录");
return result;
}
4.需要添加 json 转换组件
当请求过来的数据是json格式的数据时需要进行数据的转换,原生的servlet需要自己进行数据格式的转化,但是Spring web不需要。
原生的servlet数据格式转换:
response.getWriter().write(new ObjectMapper().writeValueAsString(result));
<!--jackson-->< dependency >< groupId >com.fasterxml.jackson.core</ groupId >< artifactId >jackson-databind</ artifactId >< version >2.13.3</ version ></ dependency >
6.返回 JSON
@RequestMapping(path = "/login",method = RequestMethod.POST)
public Result login(@RequestBody Admin admin){
Result result = new Result(200,"登录成功",admin1);
return result;
}
四.拦截器
(1)关于拦截器:
Spring WEB 中的拦截器(Interceptor)类似于 Servlet 中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。Spring 中的拦截器与过滤器有着本质的区别,过滤器是 servlet 规范中定义并实 现的,在进入到 servlet 之前截获请求.而拦截器是 spring 中定义的一种拦截机制, 是对进入到处理器的请求进行拦截。(servlet过滤器的范围比Springweb的范围大得多)
SpringWEB 定义了拦截器接口 HandlerInterceptor调用这个三个方法的时候,其参数的值也是从框架内部传递进来的。boolean preHandle预处理方法,实现处理器方法的预处理,就是在处理器方法执行之前这个方法会 被执行,相当于拦截了处理器方法,框架会传递请求和响应对象给该方法,第三 个参数为被拦截的处理器。如果 preHandle 方法返回 true 表示继续流程(如调 用下一个拦截器或处理器方法),返回 false 表示流程中断,不会继续调用其他 的拦截器或处理器方法,此时我们需要通过 response 来产生响应;
拦截器实例如下:
package com.ffyc.ssm.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffyc.ssm.model.Result;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//拦截器处理方法:
/*
请求到达处理器之前进入到拦截器
返回true离开拦截器到达处理器
* */
public class AdminTokeninterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String adminToken=request.getHeader("adminToken");//获得请求头中的adminToken身份令牌
System.out.println(adminToken);
if(adminToken.equals("123456"))//判断客户端传来的adminToken身份令牌有没有问题,正确就放行,通过拦截器到达自定义处理器
{
return true;
}
else {
Result result = new Result(400, "Token验证失败", null);
response.getWriter().write(new ObjectMapper().writeValueAsString(result));
}
return false;
}
}
(2)拦截器的实现
(1)添加 servlet api 依赖
(2)编写一个类,继承 HandlerInterceptorAdapter
(3)在xml文件中注册拦截器
<!--servlet依赖-->< dependency >< groupId >javax.servlet</ groupId >< artifactId >javax.servlet-api</ artifactId >< version >4.0.1</ version >< scope >provided</ scope ></ dependency >
编写一个类,继承 HandlerInterceptorAdapter
public class DemoInterceptor implements HandlerInterceptor{
/* 当请求到达控制器之前被执行
true--继续向下执行,到达下一个拦截器,或控制器
false--不会继续向下执行
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler)throws Exception {
System.out.println("之前执行");
return false;
}