一、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
<?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) 处理器类搭建
java
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组件的同学需要自行生成相关方法
java
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直接返回响应
java
@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方法
java
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--不再向后执行
*/
@Override
public 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)编码拦截器
在不适用框架时,我们需要自己创建编码过滤器
java
package com.wbc.dorm.filter;
import javax.servlet.*;
import java.io.IOException;
public class EncodingFilter implements Filter {
String reqencod="";
String respencod="";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化过滤器");
reqencod=filterConfig.getInitParameter("reqencod");
respencod=filterConfig.getInitParameter("respencod");
}
@Override
public void destroy() {
System.out.println("过滤器销毁时执行");
}
//执行过滤操作的方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("编码过滤器");
//设置请求编码集
servletRequest.setCharacterEncoding(reqencod);
//设置响应编码集
servletResponse.setContentType(respencod);
//让请求离开过滤器,继续向下执行,下一个可能是过滤器,也可能是目标访问的servlet
filterChain.doFilter(servletRequest, servletResponse);
}
}
并在web.xml中配置
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中配置即可
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>