Java关于Http请求的各种参数或行为的获取

本文介绍了如何利用HttpServletRequest接口获取HTTP请求信息,包括请求方法、URI、参数等。接着讲解了注解的使用,如@Target和@Retention,以及如何创建并使用自定义注解。最后,展示了如何通过Spring AOP的环绕通知实现操作日志的记录,包括切入点、通知方法和异常处理,以此实现对系统操作的追踪和日志保存。
摘要由CSDN通过智能技术生成
HttpServletRequest的作用及用法        

http请求头以及ip、参数等信息都包含其中。

方法声明功能描述
String getMethod()该方法用于获取 HTTP 请求消息中的请求方式(如 GET、POST 等)
String getRequestURI()该方法用于获取请求行中的资源名称部分即位于 URL 的主机和端门之后、参数部分之前的部分
String getQueryString()该方法用于获取请求行中的参数部分,也就是资源路径后问号(?)以后的所有内容
String getContextPath()该方法用于获取请求 URL 中属于 Web 应用程序的路径,这个路径以 / 开头,表示相对于整个 Web 站点的根目录,路径结尾不含 /。如果请求 URL 属于 Web 站点的根目录,那么返回结果为空字符串("")
String getServletPath()该方法用于获取 Servlet 的名称或 Servlet 所映射的路径
String getRemoteAddr()该方法用于获取请求客户端的 IP 地址,其格式类似于 192.168.0.3
String getRemoteHost()该方法用于获取请求客户端的完整主机名,其格式类似于 pcl.mengma.com。需要注意的是,如果无法解析出客户机的完整主机名,那么该方法将会返回客户端的 IP 地址
int getRemotePort()该方法用于获取请求客户端网络连接的端口号
String getLocaIAddr()该方法用于获取 Web 服务器上接收当前请求网络连接的 IP 地址
String getLocalName()该方法用于获取 Web 服务器上接收当前网络连接 IP 所对应的主机名
int getLocalPort()该方法用于获取 Web 服务器上接收当前网络连接的端口号
String getServerName()该方法用于获取当前请求所指向的主机名,即 HTTP 请求消息中 Host 头字段所对应的主机名部分
int gctServcrPort()该方法用于获取当前请求所连接的服务器端口号,即 HTTP 请求消息中 Host 头字段所对应的端口号部分
StringBuffcr getRequestURL()

该方法用于获取客户端发出请求时的完整 URL,包括协议、服务器名、端口号、 资源路径等信息,但不包括后面的査询参数部分。注意,getRequcstURL() 方法返冋的结果是 StringBuffer 类型,而不是 String 类型,这样更便于对结果进行修改

获取请求消息头的相关方法

当浏览器发送 Servlet 请求时,需要通过请求消息头向服务器传递附加信息,例如,客户端可以接收的数据类型、压缩方式、语言等。为此,在 HttpServletRequest 接口中定义了一系列用于获取 HTTP 请求头字段的方法。

方法声明功能描述
String getHeader(String name)该方法用于获取一个指定头字段的值,如果请求消息中没有包含指定的头字段,则 getHeader() 方法返回 null;如果请求消息中包含多个指定名称的头字段,则 getHeader() 方法返回其中第一个头字段的值
Enumeration getHeaders(String name)
该方法返回一个 Enumeration 集合对象,该集合对象由请求消息中出现的某个指定名称的所有头字段值组成。在多数情况下,一个头字段名在请求消息中只出现一次,但有时可能会出现多次
Enumeration getHeaderNames()该方法用于获取一个包含所有请求头字段的 Enumeration 对象
int getIntHeader(String name)该方法用于获取指定名称的头字段,并且将其值转为 int 类型。需要注意的是,如果指定名称的头字段不存在,则返回值为 -1;如果获取到的头字段的值不能转为 int 类型,则将发生 NumberFormatException 异常
long getDateHeader(String name)该方法用于获取指定头字段的值,并将其按 GMT 时间格式转换为一个代表日期/时间的长整数,该长整数是自 1970 年 1 月 1 日 0 时 0 分 0 秒算起的以毫秒为单位的时间值
String getContentType()该方法用于获取 Content-Type 头字段的值,结果为 String 类型
int getContentLength()该方法用于获取 Content-Length 头字段的值,结果为 int 类型
String getCharacterEncoding()该方法用于返回请求消息的实体部分的字符集编码,通常是从 Content-Type 头字段中进行提取,结果为 String 类型

可用于请求验证,验证用户是否登录或者登录是可以保存系统操作日志,将操作人员、路径、参数、状态等信息存入数据库中,甚至可以通过存入的路径与参数进行重新调用。

保存系统日志的方法

一、写一个切面,用于记录日志内容等信息。

@Target 说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
  作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

取值(ElementType)有:
    1.CONSTRUCTOR:用于描述构造器
    2.FIELD:用于描述域
    3.LOCAL_VARIABLE:用于描述局部变量
    4.METHOD:用于描述方法
    5.PACKAGE:用于描述包
    6.PARAMETER:用于描述参数
    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention注解按生命周期来划分可分为3类:

1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;

这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。

那怎么来选择合适的注解生命周期呢?

首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解。

创建一个注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {

    /**
     * 日志内容
     *
     */
    String value() default "";

    /**
     * 操作类型或者操作方类型,比如小程序或者pc端,可自定义也可舍弃
     *
     */
    int type() default 0;
}

配置切入点:注释中引号的部分为自己创建的注解的路径,可以通过该注解请求到切入点中去。

@Pointcut("@annotation(cn.nhd.cms.annotation.Log)")

public void logPointcut() {

// 该方法无方法体,主要为了让同类中其他方法使用此切入点

}

配置环绕通知,使用自定义方法上注册的切入点。

@Around("logPointcut()")

public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {

}

JointPoint是程序运行过程中可识别的点,这个点可以用来作为AOP切入点。JointPoint对象则包含了和切入相关的很多信息。比如切入点的对象,方法,属性等。我们可以通过反射的方式获取这些点的状态和信息,用于追踪tracing和记录logging应用信息。

ProceedingJoinPoint :继承了JoinPoint,是在JoinPoint的基础上暴露出 proceed 这个方法。所以在使用切面时,可以获取到ProceedingJoinPoint 这个入参,从ProceedingJoinPoint 中可获取请求参数、参数名称等信息。

# 返回目标对象,即被代理的对象
Object getTarget();

# 返回切入点的参数
Object[] getArgs();

# 返回切入点的Signature
Signature getSignature();

# 返回切入的类型,比如method-call,field-get等等,感觉不重要 
 String getKind();

环绕通知=前置+目标方法执行+后置通知,proceed方法就是用于启动目标方法执行的

配置异常通知,与环绕通知相似,只是多一个异常值

@AfterThrowing(pointcut = "logPointcut()", throwing = "e")

到此就将一个记录日志的切面生成好了,其中的保存、获取路径、获取请求参数等需要自行通过之前的http或者切入点来进行获取并保存。

二、将需要记录操作日志的接口,每次请求都通过此切面。

自定义注解、环绕通知、异常通知的使用:

@Log(value ="操作名称" , type = 1)

该自定义注解加在需要保存操作日志的接口上,每次请求都会通过该切面,则每次请求的路径以及请求参数等信息都会记录到数据库中。

至此环绕通知以及操作日志就记录完毕了。自定义切面还可以完成其他业务需求,不仅仅局限于操作日志的保存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值