一、ssm框架
早期的ssm == spring +struts2 + mybaits
早期的spring框架没有进行web层封装,需要集成struts2使用
现在的ssm == spring+springWeb+myBatis
实际上springWeb只是spring框架中的一个模块,只是大家叫习惯了,所有仍然称为ssm
二、springWeb
1、springWeb介绍
SpringWeb 是spring框架中的一个模块,基于Servlet API构建的web框架.
springWeb 是Spring 为web层开发提供的一整套完备的解决方案。
在web层框架历经Strust1,WebWork,Strust2 等诸多产品的历代更选之后, 目前业界普遍选择了springWeb作为JavaEE项目web层开发的首选方案
2、springWeb的特点
SpringWEB是spring 家族原生产品,与IOC容器等基础设施无缝对接.
基于原生的Servlet,提供了一个前端控制器 DispatcherServlet ,开发者 无须额外开发控制器对象.
可以自动绑定用户输入,并正确地转换数据类型.
代码清新简洁,大幅度提升开发效率.
内部组件化程度高,可插拔式组件即插即用.
性能卓著,尤其适合现代大型、超大型互联网项目要求
3、springWeb运行流程
(1)springWeb组件
1)、前端控制器:
DispatcherServlet(不需要程序员开发),由框架提供,在 web.xml 中配置。
作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理 用户的请求.
2)、处理器映射器:
HandlerMapping(不需要程序员开发),由框架提供。
作用:根据请求的url查找Handler(处理器/Controller)
3)、处理器适配器:
HandlerAdapter(不需要程序员开发),由框架提供。
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler。
4)、处理器:Handler(也称之为Controller,需要工程师开发)。
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可 以去正确执行Handler。
作用:接受用户请求信息,调用业务方法处理请求,也称之为后端控制器。
(2)流程
流程图中,只有拦截器和自定义处理器handler需要程序员自己编写
4、搭建SpringWeb
(1)导入jar包
<!--springWeb--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.2.RELEASE</version></dependency></dependencies>
(2)配置DispatcherServlet
在web.xml文件中配置DispatcherServlet 配置spring核心请求分发器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"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"><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>
</web-app>
(3)开启SpringWEB注解
在spring配置文件中配置
<!--开启web注解--> <mvc:annotation-driven></mvc:annotation-driven>
(4) 处理器类搭建
package com.wbc.ssm.web;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController//通过spring IOC管理
@RequestMapping(path = "loginCtl")//类的地址
public class LoginController {@RequestMapping(path = "login")//方法的地址public String login(){System.out.println("登录");return "success";}
}
解释:
1、@RestController
用于标记在一个类上,使用它标记的类就是一个SpringWEB 控制器类(类似于@service...使得spring可以反转控制)
2、@RequestMapping(path = "")
可以用于配置类的地址和方法的地址(在类上面定义地址是不能重复的),通过地址可以让前端访问服务器
(5)获取请求
我们可以通过 apiPost模拟前端发送请求
Apipost-API 文档、设计、调试、自动化测试一体化协作平台
这里以apipost8为例
1)、定义请求方法的标签
@RequestMapping(path = "login1",method = RequestMethod.GET)//方法的地址 @RequestMapping(path = "login1",method = RequestMethod.POST)//方法的地址 @GetMapping(path = "login1") @PostMapping(path = "login1")
2)、几种请求方法
通过原始的HttpServletRequest request, HttpServletResponse response接收
@RequestMapping(path = "login1",method = RequestMethod.POST) public String login1(HttpServletRequest request, HttpServletResponse response){System.out.println(request.getParameter("account"));System.out.println(request.getParameter("password"));return "success"; }
自动注入对应的参数
参数名和请求数据名称必须一致,不一致需要通过在参数前添加注解@RequestParam("别名")
请求头中传入参数需要使用@RequestHeader("名称")接到参数
如果请求的数据类型和参数的类型不匹配,则会返回状态码400
//2、自动注入到对应参数 // 参数名和请求数据名称必须一致,不一致需要通过在参数前添加注解@RequestParam("别名") 如果在请求头中需要使用@RequestHeader("名称")接到参数 //如果请求的数据类型和参数的类型不匹配,则会返回状态码400 @RequestMapping(path = "login2",method = RequestMethod.POST) public String login2(@RequestParam("account1") String account,@RequestHeader("user-password") String password){System.out.println(account);System.out.println(password);return "success"; }
自动注入到对象
//通过对象接收 @PostMapping(path = "login3") public String login3(Admin admin,@RequestHeader("adminToken") String adminToken){System.out.println(adminToken);System.out.println(admin.getAccount());System.out.println(admin.getPassword());return "success"; }
接收json
接收json需要在对象前添加@RequestBody注解
//接收json @PostMapping(path = "login4") public String login4(@RequestBody Admin admin,@RequestHeader("adminToken") String adminToken){System.out.println(adminToken);System.out.println(admin.getAccount());System.out.println(admin.getPassword());return "success"; }
接收日期
需要在属性上方添加注释@DateTimeFormat(pattern="yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")//接收前端提交数据的日期格式 @JsonFormat(pattern = "yyyy-MM-dd")//后端向前端转json时的日期格式 private Date birthday;
(6)通过Result类相应
我这里安装了lombok组件,自动生成set get toString equals hashCode等方法,并且通过@AllArgsConstructor生成满参构造方法、@NoArgsConstructor//构造无参构造方法。如果没有安装lombok组件的同学需要自行生成相关方法
package com.wbc.ssm.model;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;@Component
/*lombok 自动生成set get toString equals hashCode
*/
@Data
@AllArgsConstructor//生成满参构造方法
@NoArgsConstructor//构造无参构造方法
public class Result {private int code;private String message;private Object data;}
通过Result直接返回响应
@PostMapping(path = "login5")public Result login5(Admin admin,@RequestHeader("adminToken") String adminToken){System.out.println(adminToken);List<Admin> admins = loginService.login();Result result = new Result(200,"success",admins);return result;}
(7)搭建拦截器
Spring WEB中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter), 它主要用于拦截用户请求并作相应的处理。
Spring 中的拦截器与过滤器有着本质的区别,过滤器是servlet规范中定义并实现的,在进入到servlet之前截获请求.而拦截器是spring中定义的一种拦截机制, 是对进入到处理器的请求进行拦截
1)拦截器实现
SpringWEB 定义了拦截器接口HandlerInterceptor 我们通过实现此接口并重写boolean preHandle方法进行拦截器布置。
我们这里通过创建模拟验证token的拦截器为例
创建一个类来实现HandlerInterceptor接口并重写preHandle方法
package com.wbc.ssm.Interceptor;import com.fasterxml.jackson.databind.ObjectMapper;
import com.wbc.ssm.model.Result;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class AdminTokenInterceptor implements HandlerInterceptor {/*拦截器处理方法当请求达到处理器前,进入到拦截器进行处理返回true--离开拦截器向后执行到达处理器返回flase--不再向后执行
*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String adminToken = request.getHeader("adminToken");if (adminToken.equals("123456")) {return true;}else {System.out.println("adminToken:"+adminToken);Result result = new Result(401,"adminToken验证失败",null);response.getWriter().write(new ObjectMapper().writeValueAsString(result));}return false;}
}
在spring.xml全局配置文件中进行配置
<!--配置token拦截器--> <mvc:interceptors><mvc:interceptor><!--所有地址都进入此拦截器--><mvc:mapping path="/**"/><!--除了/loginCtl/login5 方法--><mvc:exclude-mapping path="/loginCtl/login5"/><!--配置其id和类的位置--><bean id="admintoken" class="com.wbc.ssm.Interceptor.AdminTokenInterceptor"></bean></mvc:interceptor> </mvc:interceptors>
测试两个方法能否过拦截器
登录可过,测试过不去
说明拦截器搭建成功
2)编码拦截器
在不适用框架时,我们需要自己创建编码过滤器
package com.wbc.dorm.filter;import javax.servlet.*;
import java.io.IOException;public class EncodingFilter implements Filter {String reqencod="";String respencod="";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("初始化过滤器");reqencod=filterConfig.getInitParameter("reqencod");respencod=filterConfig.getInitParameter("respencod");}@Overridepublic void destroy() {System.out.println("过滤器销毁时执行");}//执行过滤操作的方法@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("编码过滤器");//设置请求编码集servletRequest.setCharacterEncoding(reqencod);//设置响应编码集servletResponse.setContentType(respencod);//让请求离开过滤器,继续向下执行,下一个可能是过滤器,也可能是目标访问的servletfilterChain.doFilter(servletRequest, servletResponse);}
}
并在web.xml中配置
<filter><filter-name>encoding</filter-name><filter-class>com.wbc.dorm.filter.EncodingFilter</filter-class><init-param><param-name>reqencod</param-name><param-value>utf-8</param-value></init-param><init-param><param-name>respencod</param-name><param-value>text/html;charset=utf-8</param-value></init-param></filter>
在使用spring框架时,框架给我们写好了相应的拦截器,只需要在web.xml中配置即可
<filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>