当前位置: 编程技术>移动开发
本页文章导读:
▪悬浮窗口的兑现 悬浮窗口的实现
最近一些软件有了很牛X的悬浮窗口功能,很好奇怎么实现的,刚刚终于弄出来了...原理就是调用WindowManager直接操控View,然后再配合相应的WindowManager.LayoutParams属性,就OK.........
▪ 范例5-自动换行(修订版) 实例5--自动换行(修订版)
这个实例主要是运用字体的只是,但是android自带就几种,虽然android有提供可以自己加载字体的功能,但我试了下,没发现成功的,所以我代码里面就没有弄了,就.........
▪ 使用servlet下传文件 使用servlet上传文件
--------------转载,以备查询之需---------------------- 在Web 应用程序中,用户向服务器上传文件是非常普遍的操作。使用Servlet 实现文件的上传是比较简单的。 编程.........
[1]悬浮窗口的兑现
来源: 互联网 发布时间: 2014-02-18
悬浮窗口的实现
最近一些软件有了很牛X的悬浮窗口功能,很好奇怎么实现的,刚刚终于弄出来了...原理就是调用WindowManager直接操控View,然后再配合相应的WindowManager.LayoutParams属性,就OK了。这样产生出来的View根据LayoutParams的属性不同,效果也不一样。有关具体的属性,请自行参考SDK文档。
以下代码请仅供演示:
以下转自:http://blog.csdn.net/ljl_xyf/article/details/6894220
今天发现一些软件可以在android 的桌面上显示一些浮动小窗口,经过一番查找,终于找到的,代码如下:
FloatingFunc.java:
测试代码,放到任意的 Activity 代码里就可以,可以用手拖动位置:
效果如下:
注意事项:
一定要在AndroidManifest.xml添加
系统权限,不然会出错的呀
最近一些软件有了很牛X的悬浮窗口功能,很好奇怎么实现的,刚刚终于弄出来了...原理就是调用WindowManager直接操控View,然后再配合相应的WindowManager.LayoutParams属性,就OK了。这样产生出来的View根据LayoutParams的属性不同,效果也不一样。有关具体的属性,请自行参考SDK文档。
以下代码请仅供演示:
public class myFloatView extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bb=new Button(getApplicationContext());
WindowManager wm=(WindowManager)getApplicationContext().getSystemService("window");
WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
wmParams.type=2002; //type是关键,这里的2002表示系统级窗口,你也可以试试2003。
wmParams.format=1;
wmParams.flags=40;
wmParams.width=40;
wmParams.height=40;
wm.addView(bb, wmParams);
}以下转自:http://blog.csdn.net/ljl_xyf/article/details/6894220
今天发现一些软件可以在android 的桌面上显示一些浮动小窗口,经过一番查找,终于找到的,代码如下:
FloatingFunc.java:
package hrxcframe.comm;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.test.R;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
/**
* 可以永远显示在android屏幕最上方的浮动菜单
*
* @author liujl v1.0 需要添加 <uses-permission
* android:name="android.permission.SYSTEM_ALERT_WINDOW"
* /><!--系统弹出窗口权限-->权限不然会报错
*/
public class FloatingFunc {
/**
* 浮动窗口在屏幕中的x坐标
*/
private static float x = 0;
/**
* 浮动窗口在屏幕中的y坐标
*/
private static float y = 200;
/**
* 屏幕触摸状态,暂时未使用
*/
private static float state = 0;
/**
* 鼠标触摸开始位置
*/
private static float mTouchStartX = 0;
/**
* 鼠标触摸结束位置
*/
private static float mTouchStartY = 0;
/**
* windows 窗口管理器
*/
private static WindowManager wm = null;
/**
* 浮动显示对象
*/
private static View floatingViewObj = null;
/**
* 参数设定类
*/
public static WindowManager.LayoutParams params = new WindowManager.LayoutParams();
public static int TOOL_BAR_HIGH = 0;
/**
* 要显示在窗口最前面的对象
*/
private static View view_obj = null;
/**
* 要显示在窗口最前面的方法
*
* @param context
* 调用对象Context getApplicationContext()
* @param window
* 调用对象 Window getWindow()
* @param floatingViewObj
* 要显示的浮动对象 View
*/
public static void show(Context context, Window window, View floatingViewObj) {
// 加载xml文件中样式例子代码
// ********************************Start**************************
// LayoutInflater inflater =
// LayoutInflater.from(getApplicationContext());
// View view = inflater.inflate(R.layout.topframe, null);
// wm =
// (WindowManager)context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
// 加载xml文件中样式例子代码
// *********************************End***************************
//
// 关闭浮动显示对象然后再显示
close(context);
FloatingFunc.floatingViewObj = floatingViewObj;
view_obj = floatingViewObj;
Rect frame = new Rect();
// 这一句是关键,让其在top 层显示
// getWindow()
window.getDecorView().getWindowVisibleDisplayFrame(frame);
TOOL_BAR_HIGH = frame.top;
wm = (WindowManager) context// getApplicationContext()
.getSystemService(Activity.WINDOW_SERVICE);
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
| WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_NOT_FOCUSABLE;
// 设置悬浮窗口长宽数据
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
// 设定透明度
params.alpha = 80;
// 设定内部文字对齐方式
params.gravity = Gravity.LEFT | Gravity.TOP;
// 以屏幕左上角为原点,设置x、y初始值?
params.x = (int) x;
params.y = (int) y;
// tv = new MyTextView(TopFrame.this);
wm.addView(floatingViewObj, params);
}
/**
* 跟谁滑动移动
*
* @param event
* 事件对象
* @param view
* 弹出对象实例(View)
* @return
*/
public static boolean onTouchEvent(MotionEvent event, View view) {
// 获取相对屏幕的坐标,即以屏幕左上角为原点
x = event.getRawX();
y = event.getRawY() - 25; // 25是系统状态栏的高度
Log.i("currP", "currX" + x + "====currY" + y);// 调试信息
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
state = MotionEvent.ACTION_DOWN;
// panTime();
// 获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.getX();
mTouchStartY = event.getY();
Log.i("startP", "startX" + mTouchStartX + "====startY"
+ mTouchStartY);// 调试信息
break;
case MotionEvent.ACTION_MOVE:
state = MotionEvent.ACTION_MOVE;
updateViewPosition(view);
break;
case MotionEvent.ACTION_UP:
state = MotionEvent.ACTION_UP;
updateViewPosition(view);
mTouchStartX = mTouchStartY = 0;
break;
}
return true;
}
/**
* 关闭浮动显示对象
*/
public static void close(Context context) {
if (view_obj != null && view_obj.isShown()) {
WindowManager wm = (WindowManager) context
.getSystemService(Activity.WINDOW_SERVICE);
wm.removeView(view_obj);
}
}
/**
* 更新弹出窗口位置
*/
private static void updateViewPosition(View view) {
// 更新浮动窗口位置参数
params.x = (int) (x - mTouchStartX);
params.y = (int) (y - mTouchStartY);
wm.updateViewLayout(FloatingFunc.floatingViewObj, params);
}
}测试代码,放到任意的 Activity 代码里就可以,可以用手拖动位置:
final TextView tv = new TextView(getApplicationContext());
tv.setText("http://www.my400800.cn");
tv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
FloatingFunc.onTouchEvent(arg1, tv);
return true;
}
});效果如下:
注意事项:
一定要在AndroidManifest.xml添加
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
系统权限,不然会出错的呀
[2] 范例5-自动换行(修订版)
来源: 互联网 发布时间: 2014-02-18
实例5--自动换行(修订版)
这个实例主要是运用字体的只是,但是android自带就几种,虽然android有提供可以自己加载字体的功能,但我试了下,没发现成功的,所以我代码里面就没有弄了,就弄了自带的。明天再试试效果,发现书本的代码不怎么适合android,当字体变大时,会出现按两次才能换行的bug。已经修改了.
下面是效果图:
mainView的代码:
package com.wjh.demon_5;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class MainView extends SurfaceView implements Callback,Runnable{
Thread gameThread = null;
boolean isGame = true;
SurfaceHolder holder = null;
Paint forePaint = null;
Paint backPaint = null;
int keyCode = -1;
boolean isKeyDown = false;
public int m_nWidth = 50; //显示宽度
public Typeface m_nTypeFace = null; //存储字体
public MainView(Context context) {
super(context);
// TODO Auto-generated constructor stub
setFocusable(true);
getHolder().addCallback(this);
holder = this.getHolder();
backPaint = new Paint();
backPaint.setColor(Color.BLACK);
forePaint = new Paint();
forePaint.setTypeface(Typeface.DEFAULT_BOLD);
forePaint.setTextSize(20);
forePaint.setColor(Color.RED);
}
@Override
public void run() {
// TODO Auto-generated method stub
while(isGame)
{
input();
logic();
doDraw();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//开始游戏主线程
public void start()
{
if(gameThread == null)
{
gameThread = new Thread(this);
gameThread.start();
}
}
//停止游戏主线程
public void stop()
{
isGame = false;
if(gameThread != null)
{
try {
gameThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//输入判断
public void input()
{
if( keyCode == KeyEvent.KEYCODE_DPAD_UP && isKeyDown)
{
m_nWidth = m_nWidth +(int)forePaint.getTextSize();
isKeyDown = false;
}
//如果按下方向键的下键,则调整当前行的位置
else if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN && isKeyDown)
{
m_nWidth = m_nWidth - (int)forePaint.getTextSize();
isKeyDown = false;
}
}
//逻辑判断
public void logic()
{
}
public void doDraw()
{
Canvas c = null;
try
{
c = holder.lockCanvas();
synchronized (holder) {
paint(c);
}
}finally{
if(c != null)
{
holder.unlockCanvasAndPost(c);
}
}
}
//画图
public void paint(Canvas canvas)
{
//清贫
canvas.drawRect(0, 0, getWidth(), getHeight(),backPaint);
TextAjust.AjustDrawString(canvas,forePaint,
"我要自动换行我要自动换行我要自动换行我要自动换行",
m_nWidth, 50, 50, 30 );
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
stop();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
//如果按下方向键的上键,则调整当前行的位置
this.keyCode = keyCode;
isKeyDown = true;
return true;
}
}
书上提供的换行功能源码,我把画图的改成android的,其他的没改,但代码效果不好
下面给出代码
TextAjust.java
package com.wjh.demon_5;
import android.graphics.Canvas;
import android.graphics.Paint;
public class TextAjust {
static public int ChangLine(String str, Paint paint, int linewd )
{
int wd = 0;
char ch;
for (int i = 0; i < str.length(); i++)
{
ch = str.charAt(i);
if (ch == '\n')
return i + 1;
wd += paint.getTextSize();
if (wd > linewd)
return i;
}
return 0;
}
static public void AjustDrawString(Canvas canvas,Paint paint, String strText,
int linewd, int x, int y, int yDis )
{
String subStr;
int nPos; //需要换行的位置
while (true)
{
//获得句子的断点位置
nPos = ChangLine(strText, paint, linewd );
if (nPos == 0)
{
//如果nPos为0,代表输入的字符串为空
canvas.drawText( strText, x, y,paint);
break;
}
else
{
//判断是否最后一句
if (strText.charAt(nPos - 1) == '\n' )
subStr = strText.substring(0, nPos - 1);
else
subStr = strText.substring(0, nPos);
canvas.drawText( subStr, x, y, paint);
//截断句子,继续进行处理
strText = strText.substring(nPos, strText.length());
y = y + yDis;
}
}
}
}
apk文件(将后缀改为apk):Demon_5.zip
源代码文件:Demon_5.rar
1 楼
dengminghua1016
2011-08-04
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
2 楼
dengminghua1016
2011-08-04
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
不错,真的不错!!!
3 楼
dengminghua1016
2011-08-04
4 楼
dengminghua1016
2011-08-04
jkjkkjjkljk
hjjhjkkljklj
hjjhjkkljklj
[3] 使用servlet下传文件
来源: 互联网 发布时间: 2014-02-18
使用servlet上传文件
--------------转载,以备查询之需----------------------
在Web 应用程序中,用户向服务器上传文件是非常普遍的操作。使用Servlet 实现文件的上传是比较简单的。
编程思路:下面的UploadServlet.java ,其主要功能为从InputStream 中读取文件内容,将上传文件保存在根目录下,且文件名与上传文件的文件名一致。
UploadServlet.java 的源代码如下:(代码节选)
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class UploadServlet extends HttpServlet
{
//default maximum allowable file size is 1000k
static final int MAX_SIZE = 1024000;
//instance variables to store root and success message
String rootPath, successMessage;
/**
* init method is called when servlet is initialized.
*/
public void init(ServletConfig config) throws ServletException
{
super.init(config);
//get path in which to save file
rootPath = config.getInitParameter("RootPath");
if (rootPath == null)
{
rootPath = "/";
}
/*Get message to show when upload is complete. Used only if
a success redirect page is not supplied.*/
successMessage = config.getInitParameter("SuccessMessage");
if (successMessage == null)
{
successMessage = "File upload complete!";
}
}
/**
* doPost reads the uploaded data from the request and writes
* it to a file.
*/
public void doPost(HttpServletRequest request,
HttpServletResponse response)
{
ServletOutputStream out=null;
DataInputStream in=null;
FileOutputStream fileOut=null;
try
{
/*set content type of response and get handle to output
stream in case we are unable to redirect client*/
response.setContentType("text/plain");
out = response.getOutputStream();
//get content type of client request
String contentType = request.getContentType();
out.println("\ncontentType= " + contentType);
//make sure content type is multipart/form-data
if(contentType != null && contentType.indexOf(
"multipart/form-data") != -1)
{
//open input stream from client to capture upload file
in = new DataInputStream(request.getInputStream());
//get length of content data
int formDataLength = request.getContentLength();
out.println("\nContentLength= " + formDataLength);
//allocate a byte array to store content data
byte dataBytes[] = new byte[formDataLength];
//read file into byte array
int bytesRead = 0;
int totalBytesRead = 0;
int sizeCheck = 0;
while (totalBytesRead < formDataLength=
{
//check for maximum file size violation
sizeCheck = totalBytesRead + in.available();
if (sizeCheck > MAX_SIZE)
{
out.println("Sorry, file is too large to upload.");
return;
}
….
….
}
编程技巧说明:
首先定义上传文件最大字节为1024K(1M),上传文件保存在根目录(/)下,从请求的InputStream 读取实体数据,根据请求头Content-Type 和contenLength 等值,从实体数据中解析出表单Form 数据中的filename 和Content-Type 等值,然后将实体数据中真正属于上传文件的内容保存到服务器上的根目录文件中。
其中用到涉及中文输出:
String fileStr=new String(dataBytes,"ISO8859_1");
fileOut=new FileOutputStream(rootPath+fileName);
fileOut.write(fileStr.getBytes("ISO8859_1"),0,fileStr.legth());
UploadFile.html 的源代码如下:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb_2312-80">
<title>Upload a File</title>
</head>
<body>
<h1>文件上传 </h1>
<h2>提示:您的浏览器必须能支持文件上传!</h2>
<form action="/blog_article/servlet/uploadServlet/index.html" method="POST" enctype="multipart/form-data">
<div align="left">
<pre>发送文件:<input type="file" size="40" name="upl-file"> </BR>
<input type="submit" value="开始发送" now>
<input type="reset" value="重 设"></pre>
</div>
</form>
</body>
</html>
小结:
(1) Servlet 编程要求读者已经掌握了Java 语言程序设计,最好对面向对象也有一定的了解。Java 语言程序设计最主要的是对Java 的类库的使用,同样掌握Servlet 编程也要求熟练使用Sun 公司提供的JSDK。
(2) 一个好的Servlet 程序必须要考虑得全面。由于Servlet 在服务器上执行,为客户提供服务,有时可能会有多个客户同时向一个服务器发请求,这就要求Servlet 程序必须能够保证良好的并发性。允许Servlet 并发执行,就要解决Servlet 中变量和同步访问以及共享的问题,尤其要特别注意服务器的一些昂贵的资源。另一方面,Servlet 要把处理结果返回给客户,要求Servlet 充分考虑响应的速度和响应结果的简洁明了,同时对客户的错误请求有一定的容错性。
(3) 解决Servlet 中文输出问题
当Servlet 输出的文档中有中文时,需要在Servlet 中使用下面的语句来指明:
response.setContentType("text/html;charset=gb2312");
在JSP中使用:
<%@page contentType="text/html;charset=gb2312"%>
这两者是等效的。
如果在Servlet 中文显示有问题,可从以下几方面来考虑:
* 修改区域设置---在控制面板中选择区域设置,如设为英语(美国)。
* 在编译Servlet 时加入代码选项,如:javac -encoding iso8859-1 ghqServlet.java
* 在源程序中加入编码转换函数,如:out.println(new String("请输入用户名").getBytes("GBK"),"ISO8859_1"));
或者使用下面的方法:
String Str="请输入用户名";Byte[] tempByte=Str.getBytes("ISO8859_1");String tempStr=new String(tempByte);
这样tempStr 中的中文就可以正确显示了。
由于Servlet 采用不同的引擎,其中文的解决方法可能不同;因此,当出现中文显示问题时,建议一定要多实验,最终总会得到解决。
(4) Java Servlet 程序弥补了 Applet 程序的不足, Servlet 主要应用在HTTP Servlet 接收请求(HttpServletRequest接口)和产生响应(HttpServletResponse接口)、使用Cookies 及会话管理(HttpSession 接口)应用、Java Servlet 在网络上的编程应用如利用Servlet 上传和下载文件、Servlet 的数据库编程、在Servlet 中发送和接受邮件以及Java Servlet 在RMI和XML等方面的应用,因此Servlet 的编程应用还是比较广泛的。
通常 Servlet 可以使用以下的方法调用:
* 客户通过访问 Servlet 产生的文档来调用
Server 得到一个访问文档的请求后,查找配置参数,就会发现所需文档不是一个静态文档,而是由 Servlet 对象产生的,于是服务器就会把请求传给 Servlet,Servlet 调用 "service" 方法产生输出。这种方法与传统的调用 CGI 的方法类似。
* 直接通过 URL 调用 Servlet
客户(浏览器)使用以下格式的 URL 调用:
http://Servlet_Host_Name/servlet/<servlet URL>
<servlet URL>是指向 Servlet 位置的普通的URL,它的格式如下所示:
name?para1=value1¶2=value2...
其中,name 是 Servlet 的名字,"?" 后面跟的是一串参数,para1 是第一个参数名,value1是它的值,para1 是第二个参数名,value2是它的值,以此类推。通常Servlet 存放的位置可能与服务器不在同一台机器上,这时服务器就要动态加载、初始化和执行Servlet 类。
* 通过 SSI(Server-Side Includes) 标志调用
任何一个以.sthml 为扩展名的文件都是服务器要分析的文件。在该文件中,如果出现了Servlet标志,那么服务器就会运行该Servlet,并把它的输出结果插入标志所指示的地方。
* 把 Servlet 放在/servlet/目录下
如果一个 Servlet 的类文件被放在/servlet/目录下,那么就可以直接使用它的类名调用它。
* 通过 Filter Chain 调用
这种方法一般要把 Servlet 配置成当一个特定的 MIME 类型被设置为响应时再调用。
但Servlet 也有它的缺点:
* 在复杂的HTML 网页中,加入的动态部分如果用Servlet 来处理的话,那对程序员来说简直是一场噩梦。
* Servlet 要进行编译、放入执行码等复杂的调用过程。
正是由于Servlet存在的缺点,才出现使用JSP 技术来解决上面的问题,这也正是JSP 的优点。
--------------转载,以备查询之需----------------------
在Web 应用程序中,用户向服务器上传文件是非常普遍的操作。使用Servlet 实现文件的上传是比较简单的。
编程思路:下面的UploadServlet.java ,其主要功能为从InputStream 中读取文件内容,将上传文件保存在根目录下,且文件名与上传文件的文件名一致。
UploadServlet.java 的源代码如下:(代码节选)
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class UploadServlet extends HttpServlet
{
//default maximum allowable file size is 1000k
static final int MAX_SIZE = 1024000;
//instance variables to store root and success message
String rootPath, successMessage;
/**
* init method is called when servlet is initialized.
*/
public void init(ServletConfig config) throws ServletException
{
super.init(config);
//get path in which to save file
rootPath = config.getInitParameter("RootPath");
if (rootPath == null)
{
rootPath = "/";
}
/*Get message to show when upload is complete. Used only if
a success redirect page is not supplied.*/
successMessage = config.getInitParameter("SuccessMessage");
if (successMessage == null)
{
successMessage = "File upload complete!";
}
}
/**
* doPost reads the uploaded data from the request and writes
* it to a file.
*/
public void doPost(HttpServletRequest request,
HttpServletResponse response)
{
ServletOutputStream out=null;
DataInputStream in=null;
FileOutputStream fileOut=null;
try
{
/*set content type of response and get handle to output
stream in case we are unable to redirect client*/
response.setContentType("text/plain");
out = response.getOutputStream();
//get content type of client request
String contentType = request.getContentType();
out.println("\ncontentType= " + contentType);
//make sure content type is multipart/form-data
if(contentType != null && contentType.indexOf(
"multipart/form-data") != -1)
{
//open input stream from client to capture upload file
in = new DataInputStream(request.getInputStream());
//get length of content data
int formDataLength = request.getContentLength();
out.println("\nContentLength= " + formDataLength);
//allocate a byte array to store content data
byte dataBytes[] = new byte[formDataLength];
//read file into byte array
int bytesRead = 0;
int totalBytesRead = 0;
int sizeCheck = 0;
while (totalBytesRead < formDataLength=
{
//check for maximum file size violation
sizeCheck = totalBytesRead + in.available();
if (sizeCheck > MAX_SIZE)
{
out.println("Sorry, file is too large to upload.");
return;
}
….
….
}
编程技巧说明:
首先定义上传文件最大字节为1024K(1M),上传文件保存在根目录(/)下,从请求的InputStream 读取实体数据,根据请求头Content-Type 和contenLength 等值,从实体数据中解析出表单Form 数据中的filename 和Content-Type 等值,然后将实体数据中真正属于上传文件的内容保存到服务器上的根目录文件中。
其中用到涉及中文输出:
String fileStr=new String(dataBytes,"ISO8859_1");
fileOut=new FileOutputStream(rootPath+fileName);
fileOut.write(fileStr.getBytes("ISO8859_1"),0,fileStr.legth());
UploadFile.html 的源代码如下:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb_2312-80">
<title>Upload a File</title>
</head>
<body>
<h1>文件上传 </h1>
<h2>提示:您的浏览器必须能支持文件上传!</h2>
<form action="/blog_article/servlet/uploadServlet/index.html" method="POST" enctype="multipart/form-data">
<div align="left">
<pre>发送文件:<input type="file" size="40" name="upl-file"> </BR>
<input type="submit" value="开始发送" now>
<input type="reset" value="重 设"></pre>
</div>
</form>
</body>
</html>
小结:
(1) Servlet 编程要求读者已经掌握了Java 语言程序设计,最好对面向对象也有一定的了解。Java 语言程序设计最主要的是对Java 的类库的使用,同样掌握Servlet 编程也要求熟练使用Sun 公司提供的JSDK。
(2) 一个好的Servlet 程序必须要考虑得全面。由于Servlet 在服务器上执行,为客户提供服务,有时可能会有多个客户同时向一个服务器发请求,这就要求Servlet 程序必须能够保证良好的并发性。允许Servlet 并发执行,就要解决Servlet 中变量和同步访问以及共享的问题,尤其要特别注意服务器的一些昂贵的资源。另一方面,Servlet 要把处理结果返回给客户,要求Servlet 充分考虑响应的速度和响应结果的简洁明了,同时对客户的错误请求有一定的容错性。
(3) 解决Servlet 中文输出问题
当Servlet 输出的文档中有中文时,需要在Servlet 中使用下面的语句来指明:
response.setContentType("text/html;charset=gb2312");
在JSP中使用:
<%@page contentType="text/html;charset=gb2312"%>
这两者是等效的。
如果在Servlet 中文显示有问题,可从以下几方面来考虑:
* 修改区域设置---在控制面板中选择区域设置,如设为英语(美国)。
* 在编译Servlet 时加入代码选项,如:javac -encoding iso8859-1 ghqServlet.java
* 在源程序中加入编码转换函数,如:out.println(new String("请输入用户名").getBytes("GBK"),"ISO8859_1"));
或者使用下面的方法:
String Str="请输入用户名";Byte[] tempByte=Str.getBytes("ISO8859_1");String tempStr=new String(tempByte);
这样tempStr 中的中文就可以正确显示了。
由于Servlet 采用不同的引擎,其中文的解决方法可能不同;因此,当出现中文显示问题时,建议一定要多实验,最终总会得到解决。
(4) Java Servlet 程序弥补了 Applet 程序的不足, Servlet 主要应用在HTTP Servlet 接收请求(HttpServletRequest接口)和产生响应(HttpServletResponse接口)、使用Cookies 及会话管理(HttpSession 接口)应用、Java Servlet 在网络上的编程应用如利用Servlet 上传和下载文件、Servlet 的数据库编程、在Servlet 中发送和接受邮件以及Java Servlet 在RMI和XML等方面的应用,因此Servlet 的编程应用还是比较广泛的。
通常 Servlet 可以使用以下的方法调用:
* 客户通过访问 Servlet 产生的文档来调用
Server 得到一个访问文档的请求后,查找配置参数,就会发现所需文档不是一个静态文档,而是由 Servlet 对象产生的,于是服务器就会把请求传给 Servlet,Servlet 调用 "service" 方法产生输出。这种方法与传统的调用 CGI 的方法类似。
* 直接通过 URL 调用 Servlet
客户(浏览器)使用以下格式的 URL 调用:
http://Servlet_Host_Name/servlet/<servlet URL>
<servlet URL>是指向 Servlet 位置的普通的URL,它的格式如下所示:
name?para1=value1¶2=value2...
其中,name 是 Servlet 的名字,"?" 后面跟的是一串参数,para1 是第一个参数名,value1是它的值,para1 是第二个参数名,value2是它的值,以此类推。通常Servlet 存放的位置可能与服务器不在同一台机器上,这时服务器就要动态加载、初始化和执行Servlet 类。
* 通过 SSI(Server-Side Includes) 标志调用
任何一个以.sthml 为扩展名的文件都是服务器要分析的文件。在该文件中,如果出现了Servlet标志,那么服务器就会运行该Servlet,并把它的输出结果插入标志所指示的地方。
* 把 Servlet 放在/servlet/目录下
如果一个 Servlet 的类文件被放在/servlet/目录下,那么就可以直接使用它的类名调用它。
* 通过 Filter Chain 调用
这种方法一般要把 Servlet 配置成当一个特定的 MIME 类型被设置为响应时再调用。
但Servlet 也有它的缺点:
* 在复杂的HTML 网页中,加入的动态部分如果用Servlet 来处理的话,那对程序员来说简直是一场噩梦。
* Servlet 要进行编译、放入执行码等复杂的调用过程。
正是由于Servlet存在的缺点,才出现使用JSP 技术来解决上面的问题,这也正是JSP 的优点。
最新技术文章: