- 浏览: 480327 次
文章分类
最新评论
-
itway:
多谢,正好要找c#的。多谢了。
用 C# .net framework 实现ADSL自动拨号 -
laosi0829:
...
无需刻盘,在windows XP/VISTA/7下,硬盘安装ubuntu
Java应用程序模拟向Servlet发送POST请求
package com.pat.postrequestemulator;
importjava.io.BufferedReader;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
importjava.net.HttpURLConnection;
importjava.net.URL;
public classPostRequestEmulator
{
public static void main(String[] args)throws Exception
{
// 服务地址
URL url = newURL("http://127.0.0.1:8080/test/upload");
// 设定连接的相关参数
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStreamWriter out = newOutputStreamWriter(connection.getOutputStream(), "UTF-8");
// 向服务端发送key = value对
out.write("username=kevin&password=pass");
out.flush();
out.close();
// 获取服务端的反馈
String strLine="";
String strResponse ="";
InputStream in =connection.getInputStream();
BufferedReader reader = newBufferedReader(new InputStreamReader(in));
while((strLine =reader.readLine()) != null)
{
strResponse +=strLine +"\n";
}
System.out.print(strResponse);
}
}
服务端的servlet可以这么写:
packagecom.pat.handlinghttprequestservlet;
importjava.io.IOException;
importjava.io.PrintWriter;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
public classHandlingHttpRequestServlet extends HttpServlet
{
private static final longserialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequestreq, HttpServletResponse resp)
throws ServletException, IOException
{
super.doGet(req, resp);
}
@Override
protected voiddoPost(HttpServletRequest req, HttpServletResponse resp)
throwsServletException, IOException
{
String username =req.getParameter("username"); //获取username所对应的value
String password =req.getParameter("password"); //获取password所对应的value
System.out.println("Thereceived username and password is: " + username + "/" +password);
// 向请求端发回反馈信息
PrintWriter out =resp.getWriter();
out.print("OK");
out.flush();
out.close();
super.doPost(req, resp);
}
}
一切看起来都不复杂。但是如果要模拟的表单,除了要向服务器传递如上面的“key = value”这样的普通信息,同时还要上传文件,事情就复杂得多。下面详解如下:
1. 准备
玄机逸士很久没有开发web方面的应用了,所以机器上没有现成的环境,为此先要进行这方面的准备。
a) 到http://tomcat.apache.org 上下载tomcat压缩包apache-tomcat-6.0.33.zip,将其解压到指定目录即可,
如:D:\Tomcat6
b) 到http://commons.apache.org上下载用于文件上传的两个包:commons-fileupload-1.2.2-bin.zip
和commons-io-2.1-bin.zip, commons-fileupload依赖于commons-io,但在编程的过程中,
不会直接用到commons-io
c) 检查Tomcat的安装是否成功。双击D:\Tomcat6\bin目录中的startup.bat文件,就可以启动tomcat。
打开浏览器,访问http://localhost:8080/,如果出现tomcat相关的页面,则说明tomcat安装成功。
d) 在D:\Tomcat6\webapps目录下创建一个test子目录,我们等会开发的servlet就将部署在这里。在
test目录下再建立两个目录WEB-INF(必须大写)和upload,在WEB-INF下面 创建两个目录classes和lib,
同时在新建一个web.xml文件;在upload目录下,创建一个temp子目录,这些工作做完以后,test目录
下面的目录文件结构如下图所示。
其中的classes目录,用来存放将要开发的servlet,lib用来存放commons-fileupload和commons-io相关的jar包,web.xml是一些应用描述信息;upload用于存放客户端(即我们要开发的Java application)上传过来的文件,temp则用于存放上传过程中可能产生的一些临时文件。
e) 将commons-fileupload-1.2.2-bin.zip和commons-io-2.1-bin.zip解压,可以得到commons-fileupload-
1.2.2.jar和commons-io-2.1.jar,我们将这两个文件拷贝到d)中创建的lib目录中。
f) 编辑web.xml使之如下:
<?xmlversion="1.0" encoding="ISO-8859-1"?>
<!--
Licensed to the Apache Software Foundation(ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional informationregarding copyright ownership.
The ASF licenses this file to You under theApache License, Version 2.0
(the "License"); you may not usethis file except in compliance with
the License.You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreedto in writing, software
distributed under the License is distributedon an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied.
See the License for the specific languagegoverning permissions and
limitations under the License.
-->
<web-appxmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>com.pat.handlinghttprequestservlet.HandlingHttpRequestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/upload</url-pattern>
</servlet-mapping>
</web-app>
这个web.xml可以先从D:\Tomcat6\webapps\examples\WEB-INF下面拷贝过来,再进行如上黑体字所示的修改即可。<servlet>标签描述的是servlet代码方面的资料,其中<servlet-name>Hello</servlet-name>是给这个servlet起一个名字Hello,它必须和下面的<servlet-mapping>中的<servlet-name>一致,该名字具体是什么可以随意写定。
<servlet-class>com.pat.handlinghttprequestservlet.HandlingHttpRequestServlet</servlet-class>说明了完整的servlet类名,即servlet的类名为HandlingHttpRequestServlet,它位于包com.pat.handlinghttprequestservlet中。
<url-pattern>/upload</url-pattern>,说明了如果客户端向“http://Web服务器的URL地址:端口号/test/upload”发出了请求,则该请求将由位于包com.pat.handlinghttprequestservlet中的HandlingHttpRequestServlet进行处理。
到此,前期准备工作结束。下面准备写代码。
2.Servlet的代码
packagecom.pat.handlinghttprequestservlet;
importjava.io.File;
importjava.io.IOException;
importjava.io.PrintWriter;
importjava.util.ArrayList;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.apache.commons.fileupload.FileItem;
importorg.apache.commons.fileupload.disk.DiskFileItemFactory;
importorg.apache.commons.fileupload.servlet.ServletFileUpload;
public classHandlingHttpRequestServlet extends HttpServlet
{
private static final longserialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequestreq, HttpServletResponse resp)
throws ServletException, IOException
{
super.doGet(req, resp);
}
@SuppressWarnings({"unchecked", "deprecation" })
@Override
protected voiddoPost(HttpServletRequest req, HttpServletResponse resp)
throwsServletException, IOException
{
DiskFileItemFactory factory =new DiskFileItemFactory();
String path = req.getRealPath("/upload"); //得到绝对文件夹路径,比如
// "D:\\Tomcat6\\webapps\\test\\upload"
String repositoryPath =req.getRealPath("/upload/temp"); //临时文件夹路径
factory.setRepository(newFile(repositoryPath)); // 设定临时文件夹为repositoryPath
factory.setSizeThreshold(1024* 1024); // 设定上传文件的阈值,如果上传文件大于1M,
// 就可能在repository所代 表的文件夹中产生
// 临时文件,否则直接在内存中进行处理
//System.out.println("----"+ req.getContextPath()); // 得到相对文件夹路径,比如 "/test"
// 创建一个ServletFileUpload对象
ServletFileUpload uploader =new ServletFileUpload(factory);
try
{
// 调用uploader中的parseRequest方法,可以获得请求中的相关内容,
// 即一个FileItem类型的ArrayList。FileItem是在
// org.apache.commons.fileupload中定义的,它可以代表一个文件,
// 也可以代表一个普通的form field
ArrayList<FileItem>list = (ArrayList<FileItem>)uploader.parseRequest(req);
System.out.println(list.size());
for(FileItemfileItem : list)
{
if(fileItem.isFormField()) // 如果是普通的form field
{
Stringname = fileItem.getFieldName();
Stringvalue = fileItem.getString();
System.out.println(name+ " = " + value);
}
else // 如果是文件
{
Stringvalue = fileItem.getName();
intstart = value.lastIndexOf("\\");
StringfileName = value.substring(start + 1);
// 将其中包含的内容写到path(即upload目录)下,
// 名为fileName的文件中
fileItem.write(newFile(path, fileName));
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
// 向客户端反馈结果
PrintWriter out =resp.getWriter();
out.print("OK");
out.flush();
out.close();
super.doPost(req, resp);
}
}
再在classes目录建立如下目录结构com\pat\handlinghttprequestservlet,这用来代表HandlingHttpRequestServlet这个servlet所在的包名,将编译好的HandlingHttpRequestServlet.class,拷贝到这个目录下,然后启动(或者重新启动)tomcat
3.Java application的代码
package com.pat.postrequestemulator;
importjava.io.BufferedReader;
importjava.io.DataInputStream;
importjava.io.File;
import java.io.FileInputStream;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.io.OutputStream;
importjava.io.Serializable;
importjava.net.HttpURLConnection;
importjava.net.URL;
importjava.util.ArrayList;
public classPostRequestEmulator
{
public static void main(String[] args)throws Exception
{
// 设定服务地址
String serverUrl ="http://127.0.0.1:8080/test/upload";
// 设定要上传的普通Form Field及其对应的value
ArrayList<FormFieldKeyValuePair>ffkvp = new ArrayList<FormFieldKeyValuePair>();
ffkvp.add(newFormFieldKeyValuePair("username", "Patrick"));
ffkvp.add(newFormFieldKeyValuePair("password", "HELLOPATRICK"));
ffkvp.add(newFormFieldKeyValuePair("hobby", "Computer programming"));
// 设定要上传的文件
ArrayList<UploadFileItem>ufi = new ArrayList<UploadFileItem>();
ufi.add(newUploadFileItem("upload1", "E:\\Asturias.mp3"));
ufi.add(newUploadFileItem("upload2", "E:\\full.jpg"));
ufi.add(newUploadFileItem("upload3", "E:\\dyz.txt"));
HttpPostEmulator hpe = newHttpPostEmulator();
String response =hpe.sendHttpPostRequest(serverUrl, ffkvp, ufi);
System.out.println("Responsefrom server is: " + response);
}
}
classHttpPostEmulator
{
//每个post参数之间的分隔。随意设定,只要不会和其他的字符串重复即可。
private static final String BOUNDARY ="----------HV2ymHFg03ehbqgZCaKO6jyH";
public StringsendHttpPostRequest(String serverUrl,
ArrayList<FormFieldKeyValuePair>generalFormFields,
ArrayList<UploadFileItem>filesToBeUploaded) throws Exception
{
// 向服务器发送post请求
URL url = newURL(serverUrl/*"http://127.0.0.1:8080/test/upload"*/);
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
// 发送POST请求必须设置如下两行
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection","Keep-Alive");
connection.setRequestProperty("Charset","UTF-8");
connection.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
// 头
String boundary = BOUNDARY;
// 传输内容
StringBuffer contentBody =new StringBuffer("--" + BOUNDARY);
// 尾
String endBoundary ="\r\n--" + boundary + "--\r\n";
OutputStream out =connection.getOutputStream();
// 1. 处理文字形式的POST请求
for(FormFieldKeyValuePairffkvp : generalFormFields)
{
contentBody.append("\r\n")
.append("Content-Disposition: form-data; name=\"")
.append(ffkvp.getKey() + "\"")
.append("\r\n")
.append("\r\n")
.append(ffkvp.getValue())
.append("\r\n")
.append("--")
.append(boundary);
}
String boundaryMessage1 =contentBody.toString();
out.write(boundaryMessage1.getBytes("utf-8"));
// 2. 处理文件上传
for(UploadFileItem ufi :filesToBeUploaded)
{
contentBody = newStringBuffer();
contentBody.append("\r\n")
.append("Content-Disposition:form-data; name=\"")
.append(ufi.getFormFieldName() +"\"; ") // form中field的名称
.append("filename=\"")
.append(ufi.getFileName() +"\"") //上传文件的文件名,包括目录
.append("\r\n")
.append("Content-Type:application/octet-stream")
.append("\r\n\r\n");
StringboundaryMessage2 = contentBody.toString();
out.write(boundaryMessage2.getBytes("utf-8"));
// 开始真正向服务器写文件
File file = newFile(ufi.getFileName());
DataInputStream dis= new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut =new byte[(int) file.length()];
bytes =dis.read(bufferOut);
out.write(bufferOut,0, bytes);
dis.close();
contentBody.append("------------HV2ymHFg03ehbqgZCaKO6jyH");
StringboundaryMessage = contentBody.toString();
out.write(boundaryMessage.getBytes("utf-8"));
//System.out.println(boundaryMessage);
}
out.write("------------HV2ymHFg03ehbqgZCaKO6jyH--\r\n".getBytes("UTF-8"));
// 3. 写结尾
out.write(endBoundary.getBytes("utf-8"));
out.flush();
out.close();
// 4. 从服务器获得回答的内容
String strLine="";
String strResponse ="";
InputStream in =connection.getInputStream();
BufferedReader reader = newBufferedReader(new InputStreamReader(in));
while((strLine =reader.readLine()) != null)
{
strResponse +=strLine +"\n";
}
//System.out.print(strResponse);
return strResponse;
}
}
classFormFieldKeyValuePair implements Serializable
{
private static final longserialVersionUID = 1L;
// The form field used for receivinguser's input,
// such as "username" in "<inputtype="text" name="username"/>"
private String key;
// The value entered by user in thecorresponding form field,
// such as "Patrick" the abovementioned formfield "username"
private String value;
public FormFieldKeyValuePair(Stringkey, String value)
{
this.key = key;
this.value = value;
}
public String getKey()
{
return key;
}
public void setKey(String key)
{
this.key = key;
}
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
}
classUploadFileItem implements Serializable
{
private static final longserialVersionUID = 1L;
// The form field name in a form used foruploading a file,
// such as "upload1" in "<inputtype="file" name="upload1"/>"
private String formFieldName;
// File name to be uploaded, thefileName contains path,
// such as "E:\\some_file.jpg"
private String fileName;
public UploadFileItem(StringformFieldName, String fileName)
{
this.formFieldName =formFieldName;
this.fileName = fileName;
}
public String getFormFieldName()
{
return formFieldName;
}
public void setFormFieldName(StringformFieldName)
{
this.formFieldName =formFieldName;
}
public String getFileName()
{
return fileName;
}
public void setFileName(StringfileName)
{
this.fileName = fileName;
}
}
4.运行结果
运行PostRequestEmulator之前,服务器的upload目录下的情况:
运行PostRequestEmulator后,服务器的upload目录下的情况:
PostRequestEmulator从服务端得到的反馈情况:
Response fromserver is: OK
Tomcat控制台输出:
如果上传的文件中有大于1M的情况,第二次执行PostRequestEmulator的时候,就会在temp目录中产生临时文件。
本文参考材料:
http://v.youku.com/v_show/id_XMjc0ODMxMTA4.html
http://www.iteye.com/topic/1116110(在Android中用Application模拟http post请求)
http://apps.hi.baidu.com/share/detail/46728849
http://www.eoeandroid.com/thread-22679-1-1.html
http://blog.zhaojie.me/2011/03/html-form-file-uploading-programming.html
相关推荐
WebServices在服务端和客户端使用SOAP消息格式来传递数据,我们使用Servlet来模拟SOAP消息的客户端和服务端。
java Java Servlet小程序 java Java Servlet小程序 java Java Servlet小程序
servlet中实现请求转发,用户登录,在servlet中验证用户名和密码.
在JAVA中如何用SERVLET处理Http Post的表单请求xml
c# post发送到java servlet 并可以通过servlet HttpServletReques 的getParameter方法获取
android中java与服务器端servlet发送JSON数据请求-附件资源
Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。 它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用程序)的中间层。 Servlet是...
Java Web基础与实例教程的PPT,自己制作的PPT,将近400页,免费分享,童鞋们努力学习吧。
何为Servlet? ... Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机。
Java_Servlet技术概述和实例,Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。 它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用...
Web编程(Java )-Servlet API中请求和响应的应用
Servlet技术是Java Web开发中常用的一种技术,用于响应用户请求并生成动态内容。本文将介绍Servlet技术的基本原理以及使用方式。 首先,Servlet是一个Java类,它可以接收HTTP请求并且生成HTTP响应。当服务器接收到...
HttpClient模拟http发送post和get请求
Java期末大作业 基于Java+JSP+Servlet实现的租车管理系统源码 Java期末大作业 基于Java+JSP+Servlet实现的租车管理系统源码 Java期末大作业 基于Java+JSP+Servlet实现的租车管理系统源码 Java期末大作业 基于Java+...
servlet3异步请求,需要安装gradle,执行scripts/gradle-eclipse.bat/sh 然后导入eclipse
Java程序设计 12 JSP Servlet.ppt
java servlet 微信点餐小程序 微信小程序 mysql 毕设
如何向客户端发送响应 知道如何解决web开发中的中文乱码问题,知道乱码问题产生的原因和解决方法 会debug服务端代码 什么是Servlet Servlet是Java web应用中最核心的组件,完全用Java语言编写,它运行于服务端,它...
Java+servlet+jsp页面ajax请求 有详细的注释
java帮助文档\servlet docjava帮助文档\servlet docjava帮助文档\servlet docjava帮助文档\servlet doc