Apache HttpClient之Servelet

使用httpclient访问servlet java 使用httpclient访问servlet,方便两个不同服务器上的程序相互调用. 立即下载

本篇文章采用apatche httpclient与远程服务器建立连接

服务端:

处理用户的Servelet只是前段控制器,它的作用主要有三个:

1.获取请求参数

2.调用业务逻辑组件的方法来处理用户请求

3.根据处理结果进行输出

由于Servelet都需要获取Spring容器中的业务逻辑组件,因此提供一个公共的基类,定义一个一个方法获取web应用中的spring容器。

package org.crazyit.auction.servlet.base;

import javax.servlet.*;
import javax.servlet.http.*;

import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.context.ApplicationContext;

public class BaseServlet extends HttpServlet
{
	private ApplicationContext ctx;
	public void init(ServletConfig config)
		throws ServletException
	{
		super.init(config);
		// 获取Web应用中的ApplicationContext实例
		ctx = WebApplicationContextUtils
			.getWebApplicationContext(getServletContext());
	}
	// 返回Web应用中的Spring容器
	public ApplicationContext getCtx()
	{
		return this.ctx;
	}
}
该Servelet基类中定义了一个getCtx()方法,通过该方法可以获得spring容器,服务器端的servelet只要继承这个基类就可以通过该方法获取spring容器

示例:处理登录的Servelet

package org.crazyit.auction.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

import org.crazyit.auction.servlet.base.BaseServlet;
import org.crazyit.auction.service.AuctionManager;
import java.io.*;
import org.json.*;


@WebServlet(urlPatterns="/android/login.jsp")
public class LoginServlet extends BaseServlet
{
    public void service(HttpServletRequest request ,
		HttpServletResponse response)
		throws IOException , ServletException
	{
		String user = request.getParameter("user");
		String pass = request.getParameter("pass");
		// 获取系统的业务逻辑组件
		AuctionManager auctionManager = (AuctionManager)getCtx().getBean("mgr");
		// 验证用户登录
		int userId = auctionManager.validLogin(user , pass);
		response.setContentType("text/html; charset=GBK");
		// 登录成功
		if (userId > 0)
		{
			request.getSession(true).setAttribute("userId" , userId);
		}
		try
		{
			// 把验证的userId封装成JSONObject
			JSONObject jsonObj = new JSONObject()
				.put("userId" , userId);
			// 输出响应
			response.getWriter().println(jsonObj.toString());
		}
		catch (JSONException ex)
		{
			ex.printStackTrace();
		}
	}
}
示例中@WebServelet指定了Servelet的url为/android/login.jsp
<span style="white-space:pre">	</span>validLogin()方法用来处理用户登录。如果登录成功,程序将用户ID放入http session中,方便程序跟踪用户的状态。

客服端:

<span style="font-size:18px;">采用Apatche HttpClient与远程服务器通信,定义一个工具类对HttpClient进行封装,定义如下两个方法</span>
<span style="white-space:pre">	</span>GetRequest()发送get请求
<span style="white-space:pre">	</span>PostRequest()发送post请求
package org.crazyit.auction.client.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpUtil
{
	// 创建HttpClient对象
	public static HttpClient httpClient = new DefaultHttpClient();
	public static final String BASE_URL =
		"http://192.168.1.88:8888/auction/android/";
	/**
	 *
	 * @param url 发送请求的URL
	 * @return 服务器响应字符串
	 * @throws Exception
	 */
	public static String getRequest(final String url)
		throws Exception
	{
		FutureTask<String> task = new FutureTask<String>(
		new Callable<String>()
		{
			@Override
			public String call() throws Exception
			{
				// 创建HttpGet对象。
				HttpGet get = new HttpGet(url);
				// 发送GET请求
				HttpResponse httpResponse = httpClient.execute(get);
				// 如果服务器成功地返回响应
				if (httpResponse.getStatusLine()
					.getStatusCode() == 200)
				{
					// 获取服务器响应字符串
					String result = EntityUtils
						.toString(httpResponse.getEntity());
					return result;
				}
				return null;
			}
		});
		new Thread(task).start();
		return task.get();
	}

	/**
	 * @param url 发送请求的URL
	 * @param params 请求参数
	 * @return 服务器响应字符串
	 * @throws Exception
	 */
	public static String postRequest(final String url
		, final Map<String ,String> rawParams)throws Exception
	{
		FutureTask<String> task = new FutureTask<String>(
		new Callable<String>()
		{
			@Override
			public String call() throws Exception
			{
				// 创建HttpPost对象。
				HttpPost post = new HttpPost(url);
				// 如果传递参数个数比较多的话可以对传递的参数进行封装
				List<NameValuePair> params = 
					new ArrayList<NameValuePair>();
				for(String key : rawParams.keySet())
				{
					//封装请求参数
					params.add(new BasicNameValuePair(key 
						, rawParams.get(key)));
				}
				// 设置请求参数
				post.setEntity(new UrlEncodedFormEntity(
					params, "gbk"));
				// 发送POST请求
				HttpResponse httpResponse = httpClient.execute(post);
				// 如果服务器成功地返回响应
				if (httpResponse.getStatusLine()
					.getStatusCode() == 200)
				{
					// 获取服务器响应字符串
					String result = EntityUtils
						.toString(httpResponse.getEntity());
					return result;
				}
				return null;
			}
		});
		new Thread(task).start();
		return task.get();
	}
}<strong style="font-size:18px;">
</strong>

用户登录客户端:

<span style="font-size:14px;">package org.crazyit.auction.client;

import java.util.HashMap;
import java.util.Map;

import org.crazyit.auction.client.util.DialogUtil;
import org.crazyit.auction.client.util.HttpUtil;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;


public class Login extends Activity
{
	// 定义界面中两个文本框
	EditText etName, etPass;
	// 定义界面中两个按钮
	Button bnLogin, bnCancel;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);
		// 获取界面中两个编辑框
		etName = (EditText) findViewById(R.id.userEditText);
		etPass = (EditText) findViewById(R.id.pwdEditText);
		// 获取界面中的两个按钮
		bnLogin = (Button) findViewById(R.id.bnLogin);
		bnCancel = (Button) findViewById(R.id.bnCancel);
		// 为bnCancal按钮的单击事件绑定事件监听器
		bnCancel.setOnClickListener(new HomeListener(this));
		bnLogin.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				// 执行输入校验
				if (validate())  //①
				{
					// 如果登录成功
					if (loginPro())  //②
					{
						// 启动Main Activity
						Intent intent = new Intent(Login.this
							, AuctionClientActivity.class);
						startActivity(intent);
						// 结束该Activity
						finish();
					}
					else
					{
						DialogUtil.showDialog(Login.this
							, "用户名称或者密码错误,请重新输入!", false);
					}
				}
			}
		});
	}

	private boolean loginPro()
	{
		// 获取用户输入的用户名、密码
		String username = etName.getText().toString();
		String pwd = etPass.getText().toString();
		JSONObject jsonObj;
		try
		{
			jsonObj = query(username, pwd);
			// 如果userId 大于0
			if (jsonObj.getInt("userId") > 0)
			{
				return true;
			}
		}
		catch (Exception e)
		{
			DialogUtil.showDialog(this
				, "服务器响应异常,请稍后再试!", false);
			e.printStackTrace();
		}

		return false;
	}

	// 对用户输入的用户名、密码进行校验
	private boolean validate()
	{
		String username = etName.getText().toString().trim();
		if (username.equals(""))
		{
			DialogUtil.showDialog(this, "用户账户是必填项!", false);
			return false;
		}
		String pwd = etPass.getText().toString().trim();
		if (pwd.equals(""))
		{
			DialogUtil.showDialog(this, "用户口令是必填项!", false);
			return false;
		}
		return true;
	}

	// 定义发送请求的方法
	private JSONObject query(String username, String password)
		throws Exception
	{
		// 使用Map封装请求参数
		Map<String, String> map = new HashMap<String, String>();
		map.put("user", username);
		map.put("pass", password);
		// 定义发送请求的URL
		String url = HttpUtil.BASE_URL + "login.jsp";
		// 发送请求
		return new JSONObject(HttpUtil.postRequest(url, map));
	}
}</span>
上面activity的query()方法中两行粗体字代码用于向指定URL发送请求,并将服务器响应封装成JSONObject。


RGB接口电容触摸屏驱动(一)模块介绍 阅读详情

相关推荐

【Bug已解决】claude: command not found 解决方案

方案适用场景推荐指数添加 PATH全局 bin 目录确实存在但未加入 PATH⭐⭐⭐⭐⭐nvm 重新安装多 Node 版本切换导致失效⭐⭐⭐⭐⭐Windows 环境变量检查Windows 平台专用⭐⭐⭐⭐原生安装脚本想彻底避开 npm PATH 问题⭐⭐⭐⭐清理多重 Node 安装系统里有多套 Node 管理方式冲突⭐⭐⭐报错的核心是npm 全局安装的可执行文件路径没有正确出现在系统的 PATH 环境变量里,而不是安装本身失败了。

一键难忘的博客 1万+

HttpClient与servlet进行通信两种方法

private static void upload(String url) {         HttpClient client = new DefaultHttpClient();         HttpPost post = new HttpPost(url);         try {             ArrayList&lt;NameValuePair&gt; list =...

Tankywang的专栏 1078

Zemax与Matlab交互:双胶合优化详细流程

Zemax与Matlab交互:双胶合优化详细流程

weixin_72050316的博客 629

HttpClient应用 与 Servlet 处理文件上传

HttpClient应用 与 Servlet 处理文件上传 1、HttpClient模拟客户端提交,上传文件,提交表单 2、使用servlet处理上传的文件 现在HttpClient 版本到4 了,我现在用的是commons-httpclient-3.0.1,4和3两个版本的用法有较大的差别,另外,HttpClient依赖一些commos包,象 ‍commons-loggin

gacmy的专栏 936

22、自动化地图制作与Pandas数据处理

本文介绍了在ArcGIS Pro中使用arcpy.mp模块进行自动化地图制作的关键技术,涵盖地图元素的访问、移动与文本修改,以及将布局批量导出为JPEG、PNG和PDF格式的方法。同时,文章深入探讨了Pandas在数据处理和地理空间分析中的应用,特别是Spatially Enabled DataFrames(SEDFs)的使用。通过综合案例展示了地图更新与数据清洗、分析的结合,提升了地图制作与数据处理的效率,为GIS自动化工作流提供了实用指南。

w8x9y0z1的博客 79

Qt —— 在Win11下“Qt for Android“开发环境,通过USB在真机(华为Meta60 PRO)上调试运行,并打包APK并在真实手机运行

Qt —— 在Win11下“Qt for Android“开发环境,打包APK并在真实手机运行

314

使用httpclient post请求中文乱码解决办法

在使用httpclient发送post请求的时候,接收端中文乱码问题解决。 正文: 我们都知道,一般情况下使用post请求是不会出现中文乱码的。可是在使用httpclient发送post请求报文含中文的时候在发送端数据正常但是到了服务器端就中文乱码了。 解决办法: 发送端进行设置编码如下: 主要代码: if(null!= jsonParam) { ...

iteye_18692的博客 6968

基于SpringBoot 3 + Vue 3的全栈民宿预约管理系统设计与实现

文章将详细阐述系统的需求分析、架构设计、数据库设计、核心功能模块的实现(包括用户认证、房源管理、订单流程、支付集成等),并提供关键代码片段,最后对系统进行总结与展望。.requestMatchers("/api/admin/**").hasRole("ADMIN") // 管理员接口。.requestMatchers("/api/auth/**").permitAll() // 认证接口公开。.requestMatchers("/api/public/**").permitAll() // 公开资源。

2201_76125393的博客 272

java基于ApacheHttpClient发送Http请求实现

在HttpClient的基础上做了近一步的封装 支持json,xml格式以及其他的String数据请求。 支持资源文件上传 多文件上传,资源文件下载 支持对Http头部的修改与获取 支持Https 与 Http请求 环境 IDEA Maven3.3.9 主要的jar包 <dependency> <groupId>org.apache.httpcomponents</group

Forget_G的博客 2138

《拉依达的嵌入式\驱动面试宝典》—C/CPP基础篇(二)

《拉依达的嵌入式\驱动面试宝典》 整合了所有我认为可能遇到的技术面试问题。所有问题及其答案均是我个人学习后查阅资料总结,每个回答都做了仔细的分析,在嵌入式及其驱动面试相关问题解析做到全网独一无二。学习或者转行到嵌入式、驱动开发领域学习的不二之选

拉依达不拉跨的博客 578

Gemini-CLI 登录失败?解决报错 This account requires setting the GOOGLE_CLOUD_PROJECT env var 的问题

🚀 刚装好 `gemini-cli` 就遇到登录拦路虎?别慌!本文带你深入解析 `GOOGLE_CLOUD_PROJECT` 环境变量错误的根源,并提供超详细的图文解决方案,让你丝滑开启 AI 命令行之旅!快来抄作业!✍️

XiaoqiangClub的博客 5140

理解 Linux 动态库加载:LD_LIBRARY_PATH

flyfish

二分掌柜的 353

【OpenClaw从入门到精通】第41篇:2026年4月最新版——从零开始搭建你的第一个安全AI助理(保姆级实战教程)

2026年3月CNCERT联合发布《OpenClaw安全使用实践指南》后,安全部署成为OpenClaw使用的核心前提。本文针对新手及进阶用户,基于官方安全指引,提供三套实战部署方案:阿里云一键部署(新手首选)、Docker容器隔离部署(进阶推荐)、本地安全安装(测试专用),并详解阿里云百炼Coding Plan API接入流程。全文涵盖环境准备、分步实操、安全加固、问题排查等全流程,所有命令可直接复制执行,无需依赖外部代码库。通过本文,读者可零基础搭建安全隔离的OpenClaw AI助理,兼顾实用性与安全性

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 2200

【Linux网络】TCP 服务器并发处理多客户端:从 fork 分发到双重 fork 彻底消灭僵尸进程

拆解 TCP 服务器并发演进链:fork 分发连接、SIGCHLD 循环回收僵尸、双重 fork 交孙进程给 init 收养,并给出模型选型与线上排错对照。

2301_78967866的博客 429

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

LangGraph 本地 build 频频翻车,最终在服务器跑通流式对话

先说结论:我本地那个,一次都没成功过。三次,三次,全挂在拉镜像上。而顺得像刚上过油。这就很像我高中那辆自行车:骑着能走,一上锁就坏。那天晚上我盯着终端里那行红字看了很久,想的不是技术方案,想的是——为什么同一个工具,可以一边让我觉得自己很行,一边让我觉得自己不太行。

人工智能AI技术 116

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork

本文详解多进程TCP服务器的实现原理,从单进程并发瓶颈出发,通过fork分离连接接收与服务职责。重点解析文件描述符继承机制、僵尸进程问题及双重fork解决方案,最终构建高效、稳定的多进程服务器模型,并说明服务器重启时可能因端口未释放导致绑定失败的原因。

2402_87731470的博客 2398

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

自建 Git 服务器和裸仓库差在哪:要能提合并请求

在一台 Linux 上 git init --bare 就能自建 Git 服务器,但它只能推拉代码,没有网页、合并请求、评审和按仓库分配的权限。对照裸仓库和 AngusGit 各自能做什么,再走一遍在 AngusGit 上发起合并请求的最短路径,以及已有裸仓库怎么完整搬过来。

AngusTester 324

轻量点对点定时备份方案:个人文档与服务器文件跨机同步实践

本文探讨了轻量级文件备份场景下的实际需求与解决方案。针对个人文档及小型服务器备份,传统BAT脚本虽易上手,但存在断点续传差、安全缺失、维护困难等短板。作者提出理想方案应具备点对点传输、断点续传、加密传输、版本管理、文件过滤及自动清理等能力。最终选用松鼠备份工具,实现稳定、低运维成本的跨机同步,尤其适合中小型场景,强调“稳定省心”优于复杂功能,是小团队和个人运维的高效之选。

2501_93776716的博客 209

架设一台NFS服务器

3、将/home/tom目录仅共享给192.168.100.136这台主机,并只有用户tom可以完全访问该目录。注意:tom是一个用户目录,并且在客户端创建tom用户一定与服务端的tom用户的uid/gid保持一致。2、开放/nfs/upload目录,为192.168.100.0/24网段主机可以上传目录,并将所有用户及所属的组映射为nfs-upload,其UID和GID均为210。1、开放/nfs/shared目录,供所有用户查询资料。架设一台NFS服务器,并按照以下要求配置。

2401_87595340的博客 239

安徽京准:NTP网络校时服务器在化工厂网络部署要点

安徽京准:NTP网络校时服务器在化工厂网络部署要点

239

Linux epoll 一篇讲透:从 select/poll 到红黑树、LT/ET,再到完整 TCP 服务器

一万个客户端已经连上服务器,眼下只有十个客户端发来了数据。服务器怎样把时间花在这十个连接上?理解这个问题,就抓住了 epoll 的主线。接下来,我们沿着“为什么需要它 → 接口怎么用 → 内核如何实现 → LT/ET 怎么写 → 完整服务器怎么运行”的顺序,把知识连起来。**阅读基础:**了解socketbindlistenaccept的基本用途即可。本文示例面向 Linux,服务器使用 C++17,实验脚本使用 Python 3。

2601_94861874的博客 199

把电脑变成一台“假“GNSS 设备 —— 一个蓝牙 SPP 服务器从零到联调

本文介绍如何用Qt6实现一个蓝牙SPP服务器(H11BtServer),将电脑模拟为一台可被发现的GNSS设备。该服务器支持经典蓝牙SPP协议,注册SDP服务并监听连接,响应AT命令(如AT+DEVINFO),每秒主动推送带正确校验和的NMEA帧($GNPOS/$GGA等),数据基于时间驱动正弦与随机扰动,实现位置、精度等参数动态变化。通过解析行式协议、计算校验和、严格对齐字段顺序,可在无真实硬件情况下联调RTK客户端(如rtklib SDK或手机App),完整验证数据链路。代码结构清晰,参数集中配置,易于

Hi20240217的博客 145

Linux网络编程:彻底理解IO多路复用select!从fd_set位图、读写就绪到手写TCP多客户端字典服务器

在前面的Linux网络编程中,我们已经学习了五种经典I/O模型:其中,我们通过 配合: 将文件描述符设置为非阻塞模式。例如: 这样,在没有数据可读时: 可以立即返回: 并设置: 而不需要让当前线程一直阻塞等待。但是,这又引出了一个新的问题。假设我们的TCP服务器同时连接了100个客户端: 如果使用简单的非阻塞轮询: 服务器就需要不断检查这些Socket。即使其中99个客户端都没有发送任何数据,服务器仍然可能反复调用它们对应的 。显然,这种方式可能产生大量无意义的系统调用。我们真正希望实现的是:能不能让内核

Face_FeaR的博客 679

【服务器数据恢复】RAID5阵列双盘掉线Oracle+OA系统的数据恢复案例

某医药公司服务器组建RAID5磁盘阵列,阵列内两块硬盘先后离线,直接造成服务器宕机。服务器操作系统为RedhatLinux,承载基于Oracle数据库搭建的OA业务系统,业务数据价值高、恢复时效要求紧急。由于该OA配套Oracle版本早已停止技术支持,客户需求为:完整恢复业务数据,同时尽可能复原原有操作系统环境。

beiya123的博客 131
上一篇: java的json
下一篇: Android之ContentProvide(内容提供者)
Simple_Man_Just
博客等级 码龄11年 18粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值