struts 技巧运用

来源:互联网 发布:iis7怎么执行php 编辑:程序博客网 时间:2024/03/28 19:39

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 ToolBarSetFCKConfig.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值传给客户端,并且保存在服务器中。 如果客户后退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器保存的令牌不一致,从而有效地防止了重复提交的发生。

机制:首先在index.jsp中有一个链接,“我要留言”,

我要留言


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

0 0