获取HttpServletRequest的两种方法

一、在controller层以参数的形式直接使用
二、使用RequestContextHolder,可以直接在需要的地方使用

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();

其源码参见于FrameworkServlet中的processRequest方法
例如:
org\springframework\spring-webmvc\5.1.5.RELEASE\spring-webmvc-5.1.5.RELEASE.jar版本下的987行

	/**
	 * Process this request, publishing an event regardless of the outcome.
	 * <p>The actual event handling is performed by the abstract
	 * {@link #doService} template method.
	 */
	protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		long startTime = System.currentTimeMillis();
		Throwable failureCause = null;

		LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
		LocaleContext localeContext = buildLocaleContext(request);

		RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
		asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

		initContextHolders(request, localeContext, requestAttributes);

		try {
			doService(request, response);
		}
		catch (ServletException | IOException ex) {
			failureCause = ex;
			throw ex;
		}
		catch (Throwable ex) {
			failureCause = ex;
			throw new NestedServletException("Request processing failed", ex);
		}

		finally {
			resetContextHolders(request, previousLocaleContext, previousAttributes);
			if (requestAttributes != null) {
				requestAttributes.requestCompleted();
			}
			logResult(request, response, failureCause, asyncManager);
			publishRequestHandledEvent(request, response, startTime, failureCause);
		}
	}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
超级有影响力的Java面试题大全文档 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承:  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 3.封装:  封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性:  多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。 5、String是最基本的数据类型吗?  基本数据类型包括byte、int、char、long、float、double、boolean和short。  java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类 6、int 和 Integer 有什么区别  Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型 封装类 boolean Boolean char Character byte Byte short Short int Integer long Long float Float double Double  引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。 7、String 和StringBuffer的区别  JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用 StringBuffers来动态构造字符数据。 8、运行时异常与一般异常有何异同?  异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 9、说出Servlet的生命周期,并说出Servlet和CGI的区别。  Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。 与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。 10、说出ArrayList,Vector, LinkedList的存储性能和特性  ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 11、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别。 EJB包括Ses
Happy Captcha简易验证码是一款易于使用的Java验证码软件包,旨在花最短的时间,最少的代码量,实现Web站点的验证码功能。 Happy Captcha简易验证码提供了图片和动画两种展现形式,验证码内容包括中文(收录3500个常用汉字),阿拉伯数字(09),中文数字(零至九),中文大写数字(零至玖),数字与字母混合(09-az-AZ),数字与小写字母混合(09-az),数字与大写字母混合(09-AZ),纯小写字母,纯大写字母,大小写字母混合以及运算表达式(阿拉伯数字运算表达式和中文运算表达式)等12种类型。 Happy Captcha简易验证码完全遵循Apache 2.0开源许可协议,你可以自由使用该软件,如您在使用Happy Captcha时发现软件的任何缺陷,欢迎随时与作者联系。 Happy Captcha简易验证码安装: 如果你的项目使用的是Maven进行依赖管理,你只需向pom.xml文件添加下面的配置即可:     com.ramostear   Happy-Captcha   1.0.1   Gradle用户则可以通过引入如下的配置获取Happy Captcha: implementation 'com.ramostear:Happy-Captcha:1.0.1' Happy Captcha简易验证码使用: HappyCaptcha在设计时力求过程的简洁,在默认情况下,你只需要书写一行代码即可生成漂亮的验证码图片。下面是HappyCaptcha的使用示例: @Controller public class HappyCaptchaController{     @GetMapping("/captcha")     public void happyCaptcha(HttpServletRequest request,HttpServletResponse response){         HappyCaptcha.require(request,response).build().finish();     } } 对于HappyCaptcha而言,只有request和response是必须提供的参数,其余参数都可以使用缺省值。 在默认情况下,HappyCaptcha生成的验证码以图片形式展现,内容为09-az-A~Z的字符随机组合,字符长度为5,图片宽度为160,高度为50,字体为微软雅黑。
JAVA相关基础知识 1、面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 3.封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性: 多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。 2、String是最基本的数据类型吗? 基本数据类型包括byte、int、char、long、float、double、boolean和short。 java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类 3、int 和 Integer 有什么区别 Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型封装类 booleanBoolean charCharacter byteByte shortShort intInteger longLong floatFloat doubleDouble 引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。 4、String 和StringBuffer的区别 JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。 5、运行时异常与一般异常有何异同? 异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 6、说出Servlet的生命周期,并说出Servlet和CGI的区别。 Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。 与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。 7、说出ArrayList,Vector, LinkedList的存储性能和特性 ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 8、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别。 EJB包括Session Bean、Entity Bean、Message Driven Bea
【资源说明】 1、该资源内项目代码都是经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能。 1.1 登陆模块: * 数据库中查询用户,所以存储用户用session.setAttribute。验证用户用session.getAttribute。 * 一般进行加密存储,方式是用token(用户令牌)进行用户状态保持和验证. * 登录验证流程: ![a525034e1b26357865938eb8e1356c1](https://user-images.githubusercontent.com/52690597/155254453-c1ab8d56-a9fc-4242-97cd-e97a77670947.jpg) * 建数据库表:id,用户名,md5密码,token,是否删除,添加时间 * Dao:在配置文件中的User mapper中配置具体方法实现,原始dao层只有接口. * 方法:通过查询用户名,密码和token值返回用户对象. * 业务层(service):作为User对象获取dao层数据,判断是否需要更新token,然后返回user对象. * 控制层(controller):用StringUtils工具类判断输入的用户名和密码是否为空,再调用业务层返回user对象,最后再返回result类。 * Result类单独说:返回的结果不止包含数据,还有message告诉成功还是失败,一个code200,404来告诉具体状态,用一个const类存不同状态对应的code值,用resultgenerator来按照controller的逻辑修改result的参数(通过setter), 最后result的值和信息通过@RequestMapping指定的路径在访问这个路径时调用login方法然后显示结果. * 登录状态保持:后端实现token值是否有效,因为大部分接口都需要验证登陆,所以进行方法抽取,用aop注解切面来返回用户信息(需要自定义注解:1.@interface + 注解名,2. 元注解:修饰注解的注解,@Target:注解用在哪种java元素上, @Retention:注解的生命周期,@Documented),再用自定义方法参数解析器HandlerMethodArgumentResolver取出request header中的user,调用service层方法比较token,返回user对象。 最后在spring-mvc配置文件中配置参数解析器,直接在controller类中需要用这个注解的方法or参数上添加注解就可以自动验证token。 1.2 分页功能 * 后端按照前端的需求将分页所需数据查询出来。后端只需要提供总页数,必不可少的两个参数1 需要的页码 2 每页条数 * 数据交互流程: 1. 前端将页码和条数两个参数通过 HTTP 请求传输给后端; 2. 后端获取到这两个参数后进行参数验证,查询后将当前页的所有数据实体和数据总量封装; 3. 后端将封装数据返回给前端; 4. 前端获取到数据和数据量后分别对当前页数据进行渲染和展示,同时完成分页信息区的计算和展示。 之后定义后端数据的响应格式,在Result里,然后定义分页结果集的数据格式。 * DAO层:实现分页功能都需要在对应实体的DAO Mapper的xml文件中添加查询总数目和查询列表的sql语句(其中要包含分页的两个参数:start页数和limit每页条数)。 * Controller层:获得前端的param,验证页数和条数是否为空,最后调用业务层将PageUtil(页数类,用于获取前端发送过来的map数据中的页数和条数)对象传递过去。 * Service层:调用DAO层两个方法,返回PageResult类也就是结果集,其实最后进入了result类和code与message一起到前端。 2.1 图片管理模块:主要使用mvc的multipartResolver工具类实现文件上传。如果接受到了文件上传请求,dispatcher调用resolveMultipart方法装饰请求HttpServletRequest并返回multiHttpServletRequest类型(包含文件对象)。 具体流程: 1. 首先判断请求对象request,然后对请求头的contentType进行判断。 2. 当请求不为空&&contentType不为空&&contentType值以multipart开头,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值