WebRequest

本文详细介绍了Spring框架中的WebRequestInterceptor及其三个核心方法:preHandle、postHandle和afterCompletion的作用及应用场景。通过对这些方法的学习,读者可以更好地掌握如何在请求的不同阶段进行资源准备、数据模型修改和资源释放等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WebRequestInterceptor

WebRequestInterceptor 中也定义了三个方法,我们也是通过这三个方法来实现拦截的。这三个方法都传递了同一个参数WebRequest ,那么这个WebRequest 是什么呢?这个WebRequest 是Spring 定义的一个接口,它里面的方法定义都基本跟HttpServletRequest 一样,在WebRequestInterceptor 中对WebRequest 进行的所有操作都将同步到HttpServletRequest 中,然后在当前请求中一直传递。

复制代码
public class MyWebRequestInterceptor implements WebRequestInterceptor {
    @Override
    public void afterCompletion(WebRequest arg0, Exception arg1)
            throws Exception {
        // TODO Auto-generated method stub
    }
    @Override
    public void postHandle(WebRequest arg0, ModelMap arg1) throws Exception {
        // TODO Auto-generated method stub
    }
    @Override
    public void preHandle(WebRequest arg0) throws Exception {
        // TODO Auto-generated method stub
    }
}
复制代码

1.preHandle(WebRequest request) 方法。该方法将在请求处理之前进行调用,也就是说会在Controller 方法调用之前被调用。这个方法跟HandlerInterceptor 中的preHandle 是不同的,主要区别在于该方法的返回值是void ,也就是没有返回值,所以我们一般主要用它来进行资源的准备工作,比如我们在使用Hibernate 的时候可以在这个方法中准备一个Hibernate 的Session 对象,然后利用WebRequest 的setAttribute(name, value, scope) 把它放到WebRequest 的属性中。这里可以说说这个setAttribute 方法的第三个参数scope ,该参数是一个Integer 类型的。在WebRequest 的父层接口RequestAttributes 中对它定义了三个常量:

      SCOPE_REQUEST :它的值是0 ,代表只有在request 中可以访问。 
      SCOPE_SESSION :它的值是1 ,如果环境允许的话它代表的是一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。 
      SCOPE_GLOBAL_SESSION :它的值是2 ,如果环境允许的话,它代表的是一个全局共享的session,否则就代表普通的session,并且在该session 范围内可以访问。
 

2.postHandle(WebRequest request, ModelMap model) 方法。该方法将在请求处理之后,也就是在Controller 方法调用之后被调用,但是会在视图返回被渲染之前被调用,所以可以在这个方法里面通过改变数据模型ModelMap 来改变数据的展示。该方法有两个参数,WebRequest 对象是用于传递整个请求数据的,比如在preHandle 中准备的数据都可以通过WebRequest 来传递和访问;ModelMap 就是Controller 处理之后返回的Model 对象,我们可以通过改变它的属性来改变返回的Model 模型。

3.afterCompletion(WebRequest request, Exception ex) 方法。该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。所以在该方法中可以进行资源的释放操作。而WebRequest 参数就可以把我们在preHandle 中准备的资源传递到这里进行释放。Exception 参数表示的是当前请求的异常对象,如果在Controller 中抛出的异常已经被Spring 的异常处理器给处理了的话,那么这个异常对象就是是null 。

<think>我们正在讨论的是JEngine框架中的WebRequest模块。根据引用内容,我们可以参考UnityWebRequest的使用方式,但需要适配到JEngine的WebRequest模块。 JEngine的WebRequest模块设计初衷是为了简化网络请求操作,它提供了注册接口、发送请求以及处理回调的功能。根据引用[2]中的示例,我们可以这样使用: 1. 首先,需要注册网络接口,指定接口名称、URL以及处理响应的回调函数(还可以指定离线处理函数)。 2. 然后,在需要的时候发送请求,可以附带参数。 由于用户没有提供具体的JEngine文档,但根据引用[2]的示例,我们可以推断JEngine的WebRequest模块使用方法类似。 因此,我们可以这样实现: ```csharp using JEngine.Core; using System.Collections; public class WebRequestExample : JBehaviour { public override void Init() { // 注册网络接口 WebRequest.RegisterInterface("获取数据", "http://example.com/api/data", OnDataReceived, OnOffline); } public override void Run() { // 在某个条件触发时发送请求 // 例如,点击按钮或者初始化完成后 WebRequest.SendRequest("获取数据", "param1=value1", "param2=value2"); } private void OnDataReceived(string content) { // 处理成功返回的数据 Log.Print("收到数据: " + content); } private void OnOffline() { // 离线处理 Log.Print("网络不可用,使用离线数据"); } } ``` 注意: - 上述代码中的`WebRequest`应该是JEngine框架中的某个类(可能是`Main.m_WebRequest`的简写,或者框架提供了静态方法)。 - 注册接口时,可以指定多个参数,在发送请求时,这些参数会以表单形式传递(如示例中的`username=张三`和`password=55668899`)。 - 如果网络请求失败(如无网络),则会调用离线处理函数。 如果JEngine的WebRequest模块没有提供静态方法,可能需要通过单例来访问,例如`Main.m_WebRequest`(如引用[2]所示)。 另外,如果需要使用POST方式发送JSON数据(如引用[1]所示),可能需要调整注册接口的方式,或者使用更底层的UnityWebRequest。但是,在JEngine的WebRequest模块中,可能已经封装了这种功能,我们可以查看其文档或源码。如果没有,可能需要直接使用UnityWebRequest。 但是,用户明确要求使用JEngine的WebRequest,所以我们按照其提供的接口来使用。 如果上述方式不满足需求(比如需要发送JSON),我们可以参考引用[1]中的方式,使用UnityWebRequest手动构建,但这样就不会使用JEngine的封装了。 在JEngine的WebRequest模块中,我们可以这样发送JSON: 根据引用[2]的示例,注册接口时,我们传入的回调处理函数是处理字符串的。发送请求时,我们可以传递一个JSON字符串作为参数,但是需要设置Content-Type为application/json。然而,在JEngine的WebRequest模块中,我们可能需要通过设置请求头来实现,但当前示例没有展示如何设置请求头。 因此,如果JEngine的WebRequest模块不支持设置请求头,我们可能需要直接使用UnityWebRequest(如引用[1]所示)。 但是,为了保持使用JEngine的封装,我们可以尝试查看其是否支持。在引用[2]中,注册接口时,我们可以传入多个参数,这些参数会被处理为表单数据(默认Content-Type可能是application/x-www-form-urlencoded)。所以,如果要发送JSON,可能需要使用其他方式。 在JEngine的框架中,可能提供了更高级的封装。我们可以这样: ```csharp // 注册接口时,指定请求方法为POST,并设置请求体为JSON // 但根据引用[2]的示例,注册接口时并没有指定请求方法和请求体类型,所以可能需要查看文档 // 如果框架不支持,我们可以自己扩展,或者直接使用UnityWebRequest ``` 如果必须使用JEngine的WebRequest,且需要发送JSON,我们可以这样尝试: ```csharp // 将JSON数据作为一个参数传递,但是这样服务器端可能无法正确解析,因为Content-Type不是application/json WebRequest.SendRequest("接口名称", "jsonData=" + jsonString); ``` 然后在服务器端从表单中取出jsonData字段再解析。但这并不是标准的做法。 另一种做法是,我们可以修改JEngine的WebRequest模块的源码(如果我们有权限),使其支持设置请求头和请求体。 但是,如果用户希望保持框架的封装性,且JEngine的WebRequest模块不支持,我们可以考虑直接使用UnityWebRequest,如引用[1]所示。 综上所述,如果只是简单的表单数据,使用JEngine的WebRequest很方便。如果需要发送JSON,并且框架当前不支持,我们可以选择: 1. 使用UnityWebRequest自己实现(如引用[1]所示)。 2. 扩展JEngine的WebRequest模块。 由于问题中要求使用JEngine的WebRequest发起网络请求,我们假设用户需要的是使用JEngine封装好的功能,因此我们优先展示其标准用法(发送表单数据)。如果必须发送JSON,则建议使用UnityWebRequest。 下面,我们给出两种方式的示例: **方式一:使用JEngine的WebRequest发送表单数据** ```csharp using JEngine.Core; using System.Collections; public class WebRequestFormExample : JBehaviour { public override void Init() { // 注册接口 WebRequest.RegisterInterface("提交表单数据", "http://example.com/api/post", OnResponse, OnOffline); } public override void Run() { // 发送表单数据 WebRequest.SendRequest("提交表单数据", "name=张三", "age=20"); } private void OnResponse(string content) { Log.Print("收到响应: " + content); } private void OnOffline() { Log.Print("离线模式"); } } ``` **方式二:使用UnityWebRequest发送JSON(不使用JEngine的WebRequest封装)** ```csharp using JEngine.Core; using System.Collections; using System.Text; using UnityEngine.Networking; public class WebRequestJsonExample : JBehaviour { public override void Run() { StartCoroutine(PostJsonRequest()); } IEnumerator PostJsonRequest() { string url = "http://example.com/api/post"; string json = "{\"name\":\"张三\",\"age\":20}"; using (UnityWebRequest request = new UnityWebRequest(url, "POST")) { byte[] bodyRaw = Encoding.UTF8.GetBytes(json); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { Log.Print("收到响应: " + request.downloadHandler.text); } else { Log.PrintError($"请求失败: {request.error}"); } } } } ``` 在方式二中,我们使用了UnityWebRequest,并且使用了协程。注意,在JEngine中,我们可以使用`StartCoroutine`来启动协程。 最后,根据用户的需求,如果JEngine的WebRequest模块支持发送JSON,那么请参考其官方文档。如果不支持,则建议使用方式二。 希望这些信息能帮助到您。</think>在 JEngine 框架中发起网络请求,可以通过其内置的 `WebRequest` 模块实现。以下是详细步骤和示例代码: ### 1. 注册网络接口 首先需要注册请求接口(URL 和回调处理): ```csharp using JEngine.Core; public class WebDemo : JBehaviour { public override void Init() { // 注册接口:名称, URL, 成功回调, 失败回调 Main.m_WebRequest.RegisterInterface( "获取用户数据", "https://api.example.com/user", OnUserDataReceived, OnRequestFailed ); } } ``` ### 2. 发送请求 在需要时触发请求(支持 GET/POST): ```csharp public override void Run() { // 发送GET请求(无参数) Main.m_WebRequest.SendRequest("获取用户数据"); // 发送POST请求(带参数) var postData = new Dictionary<string, string> { {"username", "testUser"}, {"token", "abc123"} }; Main.m_WebRequest.SendRequest("获取用户数据", postData); } ``` ### 3. 处理响应结果 实现回调函数处理返回数据: ```csharp private void OnUserDataReceived(string response) { // 解析JSON响应 UserData data = JsonUtility.FromJson<UserData>(response); Log.Print($"用户名: {data.name}, 等级: {data.level}"); } private void OnRequestFailed(string error) { Log.PrintError($"请求失败: {error}"); } // JSON数据结构 [System.Serializable] public class UserData { public string name; public int level; public int exp; } ``` ### 关键特性说明 1. **自动重试机制** 当网络异常时,框架会自动重试请求(可配置重试次数)[^2]。 2. **离线模式支持** 注册接口时可添加离线回调,用于本地数据加载: ```csharp Main.m_WebRequest.RegisterInterface( "获取配置", "https://api.example.com/config", OnConfigReceived, OnOfflineConfig // 离线回调 ); ``` 3. **多请求管理** 通过 `RegisterInterface` 命名管理不同接口,避免 URL 硬编码。 4. **超时控制** 默认超时 30 秒,可通过配置修改: ```csharp Main.m_WebRequest.Timeout = 15; // 单位:秒 ``` ### 完整工作流程 ```mermaid graph TD A[注册接口] --> B[发送请求] B --> C{请求成功?} C -->|是| D[解析响应数据] C -->|否| E[触发失败回调] D --> F[更新游戏状态] E --> G[使用离线数据/重试] ``` > 注意:JEngine 的 `WebRequest` 底层基于 Unity 的 `UnityWebRequest`,但封装了重试、缓存、接口管理等便捷功能[^2][^3]。对于复杂场景(如文件下载),可直接使用 `UnityWebRequest` 的原始 API[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值