restful服务接口访问乱码 和 505错误

本文详细介绍了使用 CXF 框架发布 REST 服务时遇到的 URL 中文显示问题和参数编码问题,并提供了相应的解决方法。通过兼容处理,解决了浏览器访问与 HttpURLConnection 访问之间的差异,确保了服务的稳定性和兼容性。

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

用cxf 发部个rest服务,用浏览器访问和 HttpURLConnection 访问。


1. URL中有中文,浏览器访问正常,HttpURLConnection 失败。

解决: HttpURLConnection 方式需要做兼容处理。

queryParam 传入参数,服务实现方法中要处理,如果是乱码要转换,如果中文直接查询

if (!isChineseChar(queryParam))
 {
      queryParam = new String(queryParam.getBytes("iso8859-1"), "utf-8");
 }

// 判断中文
public static boolean isChineseChar(String str)
    {
        boolean temp = false;
        Pattern p=Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m=p.matcher(str);
        if(m.find()){
            temp =  true;
        }
        return temp;
    }

2. HttpURLConnection 请求中 参数中如果有  空格,请求则会 505错误

解决: 需要对有空格的参数 做URL编码处理。

 import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import sun.net.www.protocol.http.HttpURLConnection;

import com.alibaba.fastjson.JSONObject;

public class SingleTableRestClient 
{
    private static final String targetURL = "http://localhost:8080/agd-restful/services/restful/QueryService/queryData/*?queryParam=";
    
    public static void main(String[] args) 
    {
        JSONObject obj = new JSONObject();
        obj.put("XM", "匡匡");
        obj.put("BIRTHDAY", <span style="color:#FF6666;">getURLEncoder</span>("1988-01-01 00:00:00,1988-12-30 00:00:00"));
        
        String urls = targetURL + obj.toString();
        requestRestServer(urls);
            
    }
    
    public static JSONObject requestRestServer(String url)
    {
        JSONObject obj = new JSONObject();
         try 
         {
             URL restServiceURL = new URL(url);

             HttpURLConnection httpConnection = (HttpURLConnection) restServiceURL.openConnection();
             httpConnection.setRequestMethod("GET");
             httpConnection.setRequestProperty("Accept", "application/json");
             httpConnection.setRequestProperty("Accept-Charset", "UTF-8");
             httpConnection.setRequestProperty("contentType", "UTF-8");
            
             if (httpConnection.getResponseCode() != 200) {
                    throw new RuntimeException("HTTP GET Request Failed with Error code : "
                                  + httpConnection.getResponseCode());
             }
            
             BufferedReader responseBuffer = new BufferedReader(new InputStreamReader(
                    (httpConnection.getInputStream()),"utf-8"));

             String output = "";
             String result = "";
             System.out.println("Output from Server:  \n");

             while ((output = responseBuffer.readLine()) != null) {
                    //System.out.println(output);
                    result = output;
             }
             obj = JSONObject.parseObject(result);
             System.out.println(obj.toString());
             httpConnection.disconnect();

        } catch (MalformedURLException e) {

             e.printStackTrace();

        } catch (IOException e) {
             e.printStackTrace();

        }
         return obj;
    }
    
    @SuppressWarnings("deprecation")
    <span style="color:#FF6666;">private static String getURLEncoder(String dest)
    {
        return URLEncoder.encode(dest);
    }</span>
}
修改后  正常ok
<think>好的,我现在需要帮助用户了解如何使用Qt来访问Web服务并将结果显示在软件上。首先,我得回忆一下Qt中相关的模块类。Qt的网络模块应该是最相关的,尤其是QNetworkAccessManager,这个类用于处理网络请求。用户可能需要发送HTTP请求,比如GET或POST,然后处理返回的数据。 接下来,用户提到要显示在软件上,所以需要考虑如何将获取的数据展示出来。如果是JSON数据,可能需要使用QJson相关的类来解析,然后将结果填充到界面组件,比如QLabel、QTextEdit或者自定义的列表、表格中。如果是XML数据,可能需要用Qt的XML模块来处理,不过现在大部分Web服务都使用JSON,所以可能重点在JSON解析上。 然后,我需要考虑整个流程的步骤。首先是创建一个网络管理器,然后发送请求,等待响应,处理响应数据,最后更新UI。这里要注意的是网络请求是异步的,所以需要槽函数来处理完成后的信号,比如finished()信号。同时,错误处理也很重要,比如网络错误或者超时,需要给出提示。 可能还需要提到如何处理HTTPS请求,特别是在Qt中可能需要配置SSL证书,否则可能会出现SSL错误。这个问题用户可能会遇到,所以应该提前说明解决方案,比如在请求前设置SSL配置,或者忽略SSL错误(虽然不推荐,但在测试阶段可能有用)。 另外,界面部分,用户可能需要一个输入框输入URL或者参数,一个按钮触发请求,然后一个区域显示结果。这部分需要结合Qt的Widgets或者QML,不过用户的问题可能更偏向C++Widgets,所以重点放在QNetworkAccessManager的使用上。 示例代码的结构应该包括创建QNetworkAccessManager实例,连接其finished信号到槽函数,发送请求,然后在槽函数中处理响应数据。需要展示如何读取响应内容,解析JSON,比如使用QJsonDocument、QJsonObject、QJsonArray等类,然后将解析后的数据更新到UI组件。 还需要注意线程问题,因为网络请求是在后台线程处理的,但UI更新必须在主线程,不过Qt的信号槽机制会自动处理这一点,所以用户不需要手动切换线程,但需要确保在槽函数中进行UI操作。 另外,可能要考虑跨平台的问题,确保代码在Windows、LinuxmacOS上都能正常工作,特别是网络相关的配置,比如代理设置或者权限问题。 最后,可能还需要提到一些常见问题,比如处理CORS(跨域资源共享),但如果是桌面应用,可能不会遇到浏览器的CORS限制,不过如果Web服务端有严格的CORS策略,可能需要后端配合调整。或者,用户可能需要设置请求头,比如User-Agent或者Content-Type,特别是POST请求需要设置正确的Content-Type,比如application/json。 总结一下,步骤大概是:引入网络模块,创建网络管理器,发送请求,处理响应,解析数据,更新UI,处理错误。同时,给出一个简单的示例代码,展示整个过程,并解释关键部分。</think>以下是用Qt访问Web服务并显示数据的实现步骤: 1. 准备开发环境 - 确保已安装Qt 5.12+(推荐Qt 6.4+) - 在.pro文件中添加网络模块: ```qmake QT += core gui network ``` 2. 创建网络管理器(核心类) ```cpp QNetworkAccessManager *manager = new QNetworkAccessManager(this); ``` 3. 发送HTTP请求示例 ```cpp // GET请求示例 void MainWindow::on_getButton_clicked() { QUrl url("https://api.example.com/data"); QNetworkRequest request(url); manager->get(request); } // POST请求示例 void MainWindow::on_postButton_clicked() { QUrl url("https://api.example.com/submit"); QNetworkRequest request(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); QJsonObject json; json["key"] = "value"; QByteArray data = QJsonDocument(json).toJson(); manager->post(request, data); } ``` 4. 处理响应数据(信号槽机制) ```cpp // 在构造函数中连接信号槽 connect(manager, &QNetworkAccessManager::finished, this, &MainWindow::onRequestFinished); // 响应处理函数 void MainWindow::onRequestFinished(QNetworkReply *reply) { if(reply->error() == QNetworkReply::NoError){ QByteArray response = reply->readAll(); QJsonDocument doc = QJsonDocument::fromJson(response); // 解析JSON示例 if(!doc.isNull()){ QJsonObject obj = doc.object(); QString result = obj["result"].toString(); ui->resultLabel->setText(result); } } else { qDebug() << "Error:" << reply->errorString(); } reply->deleteLater(); } ``` 5. 界面显示建议方案 - 使用`QLabel`显示简单文本 - 使用`QTextEdit`显示格式化内容 - 使用`QTableWidget`显示表格数据 - 使用`QChart`显示可视化图表 6. 处理HTTPS安全连接(重要!) ```cpp // 在发送请求前添加 QNetworkRequest request(url); request.setSslConfiguration(QSslConfiguration::defaultConfiguration()); ``` 7. 最佳实践建议 - 使用异步请求避免界面冻结 - 添加加载状态提示(如进度条) - 实现请求重试机制 - 设置合理的超时时间(默认30秒) - 对敏感数据进行加密处理 完整示例流程: 1. 创建带有按钮文本框的UI界面 2. 点击按钮触发网络请求 3. 显示加载动画 4. 收到响应后隐藏动画 5. 解析数据并更新界面显示 6. 错误处理与用户反馈 常见问题解决方案: 1. SSL证书错误:使用`QSslSocket::supportsSsl()`检查环境支持 2. 中文乱码:设置正确编码格式 ```cpp QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QString decodedString = codec->toUnicode(response); ``` 3. 跨线程访问:使用`QMetaObject::invokeMethod`进行线程安全更新 进阶功能扩展: - 实现OAuth认证 - 支持WebSocket实时通信 - 添加本地缓存机制 - 实现分页加载功能 - 支持文件上传/下载 调试技巧: 1. 使用`qDebug() << "Response:" << response;`输出原始数据 2. 使用Postman测试API接口 3. 使用Wireshark进行网络抓包分析(仅调试环境) 学习资源推荐: 1. Qt官方文档:QNetworkAccessManager类 2. Qt网络编程示例:Network Example 3. RESTful API设计指南 4. JSON API官方规范 通过以上步骤,即可实现Qt应用程序与Web服务的完整交互流程。建议从简单GET请求开始,逐步增加错误处理、数据解析等高级功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值