struts 技巧运用
0 : FCK editor应用
fck editor是一个功能非常强大的富文本编辑工具
首先需要导入一些jar包,
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
java-core-2.4.jar
slf4j-api-1.5.2.jar
slf4j-simple-1.5.2.jar
在FCK官网上下载的Lib中就有。
在web-inf下面,复制文件夹fckeditor,包括一些js,还有xml。
在fckconfig.js中可以自定义样式:
// My ToolBarSet
FCKConfig.ToolbarSets["qiujyDefault"] = [
['Source','Templates'],
['Cut','Copy','Paste','PasteText','PasteWord'],
['Find','Replace','-','SelectAll','RemoveFormat','Table'],
['Form','Checkbox','Radio','TextField','Textarea','Select','Button'],
'/',
['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript','-','Outdent','Indent'],
['OrderedList','UnorderedList','JustifyLeft','JustifyCenter','JustifyRight','Link','Unlink'],
['TextColor','BGColor'],
['Image','Flash','Rule','Smiley'],
'/',
['Style','FontFormat','FontName','FontSize'],
['FitWindow','About']
] ;
FCKConfig.ToolbarSets["qiujyBasic"] = [
['Bold','Italic','Underline','StrikeThrough','-','OrderedList',
'UnorderedList','Rule','-','JustifyLeft','JustifyCenter','JustifyRight',
'JustifyFull','-','TextColor','BGColor','-','Smiley','About']
] ;
然后在jsp页面中,这么用:
<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
<html>
<head>
<title>fckeditor使用示例2</title>
</head>
<body>
<form action="result.jsp" method="post" target="_blank">
<FCK:editor instanceName="editorContent" value=" " />
<br />
<input type="submit" value=" 提交 " />
</form>
</body>
</html>
或者
<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
<html>
<head>
<title>fckeditor编辑定制显示</title>
</head>
<body>
<form action="result.jsp" method="post" target="_blank">
<FCK:editor instanceName="editorContent"
width="100%" height="300px"
toolbarSet="Basic" value=" "/>
<br />
<input type="submit" value=" 提交 " />
</form>
</body>
</html>
或者
<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
<html>
<head>
<title>fckeditor编辑定制显示</title>
</head>
<body>
<form action="result.jsp" method="post" target="_blank">
<FCK:editor instanceName="editorContent" value=" ">
<FCK:config SkinPath="skins/office2003/" AutoDetectLanguage="true" />
</FCK:editor>
<br />
<input type="submit" value=" 提交 "/>
</form>
</body>
</html>
或者
<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
<html>
<head>
<title>fckeditor编辑器的基本信息</title>
</head>
<body>
<p>本页面FCKeditor编辑器的基本信息</p>
<ul>
<li><FCK:check command="CompatibleBrowser" /></li>
<li><FCK:check command="FileBrowsing" /></li>
<li><FCK:check command="FileUpload" /></li>
</ul>
<hr />
<form action="result.jsp" method="post" target="_blank">
<FCK:editor instanceName="editorContent" value=" " />
<br />
<input type="submit" value=" 提交 " />
</form>
</body>
</html>
或者
<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
<html>
<head>
<title>fckeditor编辑定制显示</title>
</head>
<body>
<form action="result.jsp" method="post" target="_blank">
<FCK:editor instanceName="editorContent"
width="100%" height="200px"
toolbarSet="qiujyDefault" value=" "/>
<br />
<FCK:editor instanceName="editorContent"
width="100%" height="200px"
toolbarSet="qiujyBasic" value=" "/>
<br />
<input type="submit" value=" 提交 " />
</form>
</body>
</html>
1:利用Token解决重复提交
struts的Token机制基本原理是:服务器在处理到达的请求之前,会将请求中包含的Token值与保存在当前用户会话中的令牌值进行比较,看是否匹配。 在处理完请求后,且在回应发送给客户端之前,会产生一个新的Token值,该Token值传给客户端,并且保存在服务器中。 如果客户后退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器保存的令牌不一致,从而有效地防止了重复提交的发生。
我要留言
2:BeanUtil.copyProperties与PropertyUtil.copyProperties的用法与区别
BeanUtil 提供了对Java反射和自省API的包装,其主要目的是利用反射机制,对JavaBean的属性进行处理,属于Commons组件。
这里只介绍copyProperties,在这里有用到:
package org.njy.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.njy.bean.Admin;
import org.njy.formbean.AdminForm;
public class LoginAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 将AdminForm强转成AdminForm
AdminForm adminForm = (AdminForm) form;
// 创建一个Admin对象
Admin admin = new Admin();
// 传统做法
//admin.setUsername(adminForm.getUsername());
//admin.setPassword(adminForm.getUsername());
// 赋值
//BeanUtils.copyProperties(admin, adminForm);
PropertyUtils.copyProperties(admin, adminForm);
// 将Admin对象存放到request中
request.setAttribute("admin", admin);
return mapping.findForward("mess");
}
}
package org.njy.bean;
import java.io.Serializable;
public class Admin implements Serializable {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package org.njy.formbean;
import org.apache.struts.action.ActionForm;
public class AdminForm extends ActionForm{
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
主要区别是,PropertyUtils提供类型转换功能时,如果发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而前者不支持这个功能,但是前者速度会更快一点。
3:Struts文件上传与下载
struts文件上传有两种方法,看个人爱好
一种是利用Commons-fileupload组件上传,web.xml配置如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>FileUploadServlet</servlet-name>
<servlet-class>
com.njy.web.util.FileUploadServlet
</servlet-class>
</servlet>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FileUploadServlet</servlet-name>
<url-pattern>/fileupload.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
然后,编写上传处理类
package com.njy.web.util;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* 处理文件上传的Servlet工具类
*/
public class FileUploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
// 得到存放上传文件的目录真实路径
String filePath = this.getServletContext().getRealPath("/upload");
// 检查表单是否为multipart/form-data
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
return;
} // 失败
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// upload.setSizeMax(10* 1024 * 1024); // 文件最大尺寸,设为-1表示不受限制
// factory.setSizeThreshold(256); // 缓存大小,设为-1表示不受限制
// factory.setRepository(new File("D:\\temp")); // 设置一个临时目录,默认用容器分配的
List<FileItem> items = null; // 解析请求得到所有的文件
try {
items = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
for (FileItem item : items) { // 依次处理每个上传的文件
if (!item.isFormField()) { // 检查是否为File输入域
File fullFile = new File(item.getName());
File uploadedFile = new File(filePath, fullFile.getName());
try {
item.write(uploadedFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}
request.getRequestDispatcher("/succ.jsp").forward(request, response);
}
}
在jsp中应该做如下修改:
<h2>
使用commons-fileupload上传文件
</h2>
<hr />
<!-- 文件上传的表单的属性必设值:method="post" enctype="multipart/form-data" -->
<form action="fileupload.do" method="post"
enctype="multipart/form-data">
<table>
<tr>
<td>
请选择要上传的文件
</td>
<td>
<input type="file" name="filePath" size="50" />
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value=" 上传 " />
</td>
</tr>
</table>
</form>
<br />
<br />
第二种方法是使用struts的上传文件功能。
编写配置文件struts-config.xml
<form-beans>
<form-bean name="fileUploadForm"
type="com.njy.web.formbeans.FileUploadForm">
</form-bean>
</form-beans>
<action-mappings>
<action path="/struts_fileupload" scope="request"
type="com.njy.web.util.FileUploadAction" name="fileUploadForm">
<forward name="succ" path="/succ.jsp" />
</action>
<action path="/struts_filedownload" scope="request"
type="com.njy.web.util.FileDownloadAction" name="fileUploadForm">
<forward name="succ" path="/succ.jsp" />
</action>
</action-mappings>
编写对应的处理类:
/**
* Filename: FileUploadAction.java
* Author: niejingyu
* Createtime:Nov 13, 2008
* Copyrights 2008 niejingyu All rights reserved.
* EMail: niejingyu@gmail.com
*/
package com.njy.web.util;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import com.njy.web.formbeans.FileUploadForm;
public class FileUploadAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
FileUploadForm myForm = (FileUploadForm) form;
//FormFile用于指定存取文件的类型
FormFile fileObj = myForm.getFilePath();
// 得到存放上传文件的目录的真实路径
String dir = this.getServlet().getServletContext().getRealPath("/upload");
// 如果没有选择文件
if (fileObj == null) {
return mapping.findForward("succ");
}
//获取文件的名
String fileName = new String(fileObj.getFileName().getBytes(), "utf-8");
System.out.println(fileName);
int size = fileObj.getFileSize();
if (size > 1024 * 1024) {
return mapping.findForward("succ");
}
// 从上传文件中得到一个输入流...之后 就可以进行相应操作了…
InputStream is = fileObj.getInputStream();
BufferedOutputStream bw = new BufferedOutputStream(
new FileOutputStream(dir + "/" + fileName));
byte[] buffer = new byte[20480];
int count = 0;
while ((count = is.read(buffer)) != -1) {
bw.write(buffer, 0, count);
}
bw.flush();
bw.close();
is.close();
return mapping.findForward("succ");
}
}
那个Formfile定义如下:
/**
* Filename: FileUploadForm.java
* Author: niejingyu
* Createtime:Nov 13, 2008
* Copyrights 2008 niejingyu All rights reserved.
* EMail: niejingyu@gmail.com
*/
package com.njy.web.formbeans;
import org.apache.struts.action.ActionForm;
import org.apache.struts.upload.FormFile;
public class FileUploadForm extends ActionForm {
// 文件上传输入域在ActionForm必须定义成FormFile类型
private FormFile filePath;
public FormFile getFilePath() {
return filePath;
}
public void setFilePath(FormFile filePath) {
this.filePath = filePath;
}
}
然后在jsp中调用
<h2>
使用struts的上传文件功能
</h2>
<hr />
<!-- 文件上传的表单的属性必设值:method="post" enctype="multipart/form-data" -->
<form action="struts_fileupload.do" method="post"
enctype="multipart/form-data">
<table>
<tr>
<td>
请选择要上传的文件
</td>
<td>
<input type="file" name="filePath" size="50" />
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value=" 上传 " />
</td>
</tr>
</table>
</form>
文件下载,需要在struts-config中进行配置。
<action path="/struts_filedownload" scope="request"
type="com.njy.web.util.FileDownloadAction" name="fileUploadForm">
<forward name="succ" path="/succ.jsp" />
</action>
在类中写如下的代码:
package com.njy.web.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class FileDownloadAction extends Action {
// 实现文件的下载
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//获得要下载的文件名
String path = request.getParameter("path");
// 如果是从服务器上取就用这个获得系统的绝对路径方法。
String filepath = servlet.getServletContext().getRealPath("/" + path);
File uploadFile = new File(filepath);
InputStream fis = new FileInputStream(uploadFile);
OutputStream fos = response.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
// 这个就是弹出下载对话框的关键代码
response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(path, "utf-8"));
int bytesRead = 0;
// 用输入流进行先读,然后用输出流去写,唯一不同的是我用的是缓冲输入输出流
byte[] buffer = new byte[8192];
while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
fis.close();
bis.close();
fos.close();
bos.close();
return null;
}
}
4:Struts处理中文乱码问题总结
1: 没有配置好正确的页面编码
<%@ page contentType=”text/html; charset=UTF-8”%>
2:参数传递中文乱码
为了显示乱码,可以用System.out.println()显示变量的乱码。如果出现乱码,具体的解决方法如下所示:
在Tomcat目录中conf文件夹下的server.xml中,修改端口的标签后面加一行代码,如下。
5:Struts生成验证码
首先需要一个common-lang.jar
jsp如下
<html:img page="/validatecode.do" border="0"
onclick="this.src='/validatecode.do?'+Math.random()" alt="请输入此验证码,如看不清请点击刷新。"
style="cursor:pointer" />
struts-config.xml如下:
<action-mappings>
<action path="/validatecode"
type="org.njy.action.ValidatecodeAction">
</action>
</action-mappings>
validatecode对应的ValidatecodeAction类代码如下:
package org.njy.action;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.commons.lang.RandomStringUtils;
/**
* @struts.action validate="true"
*/
public class ValidatecodeAction extends Action {
/**
* Method execute
*
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
try {
// 定义图片的宽和长
int width = 60;
int height = 20;
// 取得一个4位随机字母数字字符串
String s = RandomStringUtils.random(4, true, true);
// 保存入session,用于与用户的输入进行比较.
// 注意比较完之后清除session.
HttpSession session = request.getSession(true);
session.setAttribute("validateCode", s);
//向客户端响应一个图片文件
response.setContentType("images/jpeg");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
ServletOutputStream out = response.getOutputStream();
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
// 设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
// 设定字体--类型,颜色,大小
Font mFont = new Font("Times New Roman", Font.PLAIN, 20);// 设置字体
g.setFont(mFont);
// 画边框
//g.setColor(Color.BLACK);
//g.drawRect(0, 0, width - 1, height - 1);
// 随机产生干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160, 200));
// 生成随机类
Random random = new Random();
for (int i = 0; i < 155; i++) {
int x2 = random.nextInt(width);
int y2 = random.nextInt(height);
int x3 = random.nextInt(12);
int y3 = random.nextInt(12);
g.drawLine(x2, y2, x2 + x3, y2 + y3);
}
String sRand = "";
for (int i = 0; i < 4; i++) {
String rand = String.valueOf(random.nextInt(10));
sRand += rand;
// 将认证码显示到图象中
g.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
g.drawString(rand, 13 * i + 6, 16);
}
// 将生成的认证码放入session中,已变action中做验证
session.setAttribute("rand", sRand);
// 图象生效
g.dispose();
// 输出图象到页面
ImageIO.write((BufferedImage) image, "JPEG", out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Color getRandColor(int fc, int bc) { // 给定范围获得随机颜色
Random random = new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
}
6:页面跳转的技巧
利用js,打开一个新的网页,关闭一个新的网页,技巧不多。
附上上面这些例子的源代码:
http://download.csdn.net/detail/chengyangyy/9118621