SpringMvc的简单入门(四)之拦截器

本文介绍SpringMVC中的过滤器与拦截器的区别,并详细解释了自定义拦截器的方法及其在防止表单重复提交中的应用。

一.过滤器与拦截器的区别

1.当浏览器访问Tomcat的时候过滤器会拦截资源,过滤器什么资源都拦截,过滤器在拦截器之前,是用来拦截servlet的

2.DispatcherServlet中央处理器 在所有的action实现之前的拦截,拦截器拦截的是action,拦截器是类似过滤器的一种资源,是SpringMvc内置实现的,必须实现一个接口HandlerInterceptor

二.自定义拦截器

拦截器原理


在mvc-servlet.xml中配置拦截器

 <!-- 该拦截器用于拦截URL上参数  -->
  <mvc:interceptors>
  	
  	<!-- 自定义拦截器 -->
  	<mvc:interceptor>
  		<!-- 要拦截的资源 path=/*拦截所有-->
  		<mvc:mapping path="/tm"/>
  		<!-- 实现拦截器类的路径 -->
  		<bean class="springmvc.less05.controller.MyInterController"></bean>
  	</mvc:interceptor>
  </mvc:interceptors>
实现接口HandlerInterceptor

package springmvc.less05.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyInterController implements HandlerInterceptor {
	//在action执行完拦截
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub

	}
	//在action执行之后拦截
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub

	}
	//在action执行之前就拦截
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		//获取设置的UUID值
		String myToken= request.getParameter("token");
		//获取session
		Object myToken1= request.getSession().getAttribute("token");
		//true 让拦截器过 false则是拦下
		//判断是否是重复提交,如何参数有值就是重复提交,需要验证重复提交
		if(myToken!=null){
			//如果session==null就是重复提交返回false拦截
			if(myToken1==null){
				return false;
			}else{
				//如果设置的UUID和session相等就不拦截action,清掉session的值
				if(myToken.equals(myToken1)){
					request.getSession().removeAttribute("token");
					return true;
				}else{
					return false;
				}
			}
		}else{
			return true;
		}
	}

}

action

package springmvc.less05.controller;

import java.io.OutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import springmvc.less05.dao.MoneyDaoImpl;
@Controller
public class InterController {
	@RequestMapping(value="/inter",method=RequestMethod.GET)
	public String quert(OutputStream os)throws Exception{
		os.write("hello".getBytes());
		return null;
	}
	@Autowired
	MoneyDaoImpl mdi;
	@RequestMapping(value="/tm",method=RequestMethod.GET)
	public String quer(Integer money,OutputStream os)throws Exception{
		//根据前台传过来的金额进行扣钱
		mdi.updateMoney(money);
		//显示剩余的金钱
		os.write(("lostedmoney is:"+mdi.selectMoney()).getBytes());
		return null;
	}
}

业务逻辑层

package springmvc.less05.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class MoneyDaoImpl {
	@Autowired
	JdbcTemplate jdbc;
	//修改金额
	public void updateMoney(int money){
		String sql="update mymoney set lostedmoney=lostedmoney-"+money+" where usid=1";
		jdbc.execute(sql);
	}
	//查询剩余金额
	public int selectMoney(){
		String sql="select lostedmoney from mymoney where usid=1";
		Integer lostedMoney=jdbc.queryForObject(sql,Integer.class);
		return lostedMoney;	
	}
	
}
前台页面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib tagdir="/WEB-INF/tags" prefix="my"%><!-- 引入防重复提交标签 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'money.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
   <form action="${pageContext.request.contextPath}/tm">
   	扣钱:<input name ='money'>
   	<!-- 引入防重复提交标签 -->
   	<my:token></my:token>
   	<input type="submit" name="扣钱">
   </form>
  </body>
</html>

三.防重复提交

防重复提交原理


 在WEB-INF设置标签 设置隐藏表单域和给session设值

<%@ tag language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@attribute name="tokename" required="false" %>
<%
String ranStr=UUID.randomUUID().toString();
String key=(tokename==null?"token":tokename);
session.setAttribute(key,ranStr);
%>
<input type='hidden' name='<%=key %>' value='<%=ranStr %>'/>


内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值