码迷,mamicode.com
首页 > 数据库 > 详细

★★JSP+Struts+Mysql构建的MVC三层框架对一张数据表的CURD

时间:2015-03-08 22:46:21      阅读:632      评论:0      收藏:0      [点我收藏+]

标签:

  1. 项目实现流程

    大体流程:搭建环境 à 开发后台 à 开发前台

    1. 建立工程(struts2CURD),拷贝jar包,建立struts.xml文件,搭建环境
    2. 建立数据库和数据源配置:dbcpconfig.properties
    3. 建立db.sql:里面全是数据库操作的一些语句
    4. 建立操作数据库的工具:*.utilDBCPUtil.java,用于加载数据源。getDataSource();
    5. *.DomainUser.java 继承ActionSupport,实现Serializable接口。

    ????写好字段;生成getset方法;建立toString方法(方便调试)

    1. 建立Dao(先接口后实现)*.DaoUserDao.java(这个要按需求来做,优先考虑返回值)

    实现功能

    界面

    方法原型

    查询所有用户

    显示

    public List<User> findAllUsers() {}

    根据查询条件查询客户

    查询

    public List<User> findUsersByCondition(String condition) {}

    添加用户到数据库

    添加

    public void addUser(User user) {}

    根据Id组件获取用户信息

    查看

    public User findUserById(String userId) {}

    修改客户信息

    编辑

    public void updateUser(User user) {}

    根据用户的ID删除记录

    删除

    public void deleteUser(String userId) {}

    1. 实现Dao接口:*.dao.implUserDaoMysqlImpl.java
    2. 建立"异常库"*.ExceptionDaoException.java
    3. 写加密工具类:*.utilMD5Util.java
    4. *.test:单元测试

    开发后台

    1. 显示信息界面:listUsers.jsp和默认主页index.jsp
    2. 建立UserService.java接口
    3. 建立UserServiceImpl.java实现UserService
    4. User.java中补充相应方法
    5. listUsers.jsp页面中添加"添加"用户的按钮链接。在User.java中添加addUser()方法。建立addUser.jsp页面,实现添加功能。

      注意:在最初开始写addUser()方法时应该通过System.out.println(this);来检验是否在控制台可以得到前台输入的数据。

      添加验证规则

    6. domain下建立验证规则(用户输入数据的规则)的xml文档:User-user_addUser-validation.xml
    7. 实现综合模糊查询功能:在listUsers.jsp中添加相应项。在User.java中添加queryCondition()方法。

      技术分享

    8. 实现删除功能……
    9. 实现编辑功能……
    10. ★★★Date转换功能,系统体现的功能不适合。建立xwork-conversion.properties文件(java.util.Date=cn.hw.convertor.

      DateConvertor)

      建立DateConvertor.java类,继承:DefaulttypeConvert类,覆盖convertValue()方法

    11. 实现查看功能…… showUser.jsp
    12. 实现下载功能……
    13. 用拦截器实现的必须登陆才能进行操作。

      *.interceptorPermissionInterceptor.java 实现Interceptor接口(注意是opensymphony的不是sun)

      在顺

    14. login.jsp
  2. 总结

  • 我们自己写的动作类继承com.opensymphony.xwork2.ActionSupport的理由

    先了解Action接口有:

    ????public static final java.lang.String SUCCESS = "success";

    ????public static final java.lang.String NONE = "none";

    ????public static final java.lang.String ERROR = "error";

    ????public static final java.lang.String INPUT = "input";

    ????public static final java.lang.String LOGIN = "login";

    ????public abstract java.lang.String execute() throws java.lang.Exception;

  1. ActionSupport实现了Action类,这样利用该类中定义的这些常量来完成页面与动作类之间的交互。
  2. ActionSupport实现了很多的实用接口,大大的简化我们自己书写动作类的开发。
    1. 开发中常利用该类中的validate()方法:会自动执行在execute()之前,如校验失败,会转入input处,必须在配置该Action时配置input属性
    2. 重载该类中的execute()方法:
    3. ActionSupport还提供了一个getText(String key)方法还实现国际化,该方法从资源文件上获取国际化信息,这样在自定义标签时可以定义一个变量为new actionsupport对象实现国际化
  • 为什么要实现Serializable接口

    一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。一般以下三种情况都需要实现Serializable接口

  1. 当你想把的内存中的对象写入到硬盘的时候。比如说你的内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中,我隔几天在把它拿出来用,那么这时候就要实现Serializable接口;
  2. 当你想用套接字在网络上传送对象的时候。在进行javaSocket编程的时候,你有时候可能要传输某一类的对象,那么也就要实现Serializable接口;最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,所以可以在网络上传输。
  3. 当你想通过RMI传输对象的时候。如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,将对象从B传送到A,就需要实现序列化接口。
  • serialVersionUID的作用 ?

    serialVersionUID:字面意思上是序列化的版本号。warning的功能,在你实现序列化的类上会有这个警告,点击会出现增加这个版本号。这个版本号就是确保了不同版本之间的兼容性,不仅能够向前兼容,还能够向后兼容,即在版本升级时反序列化仍保持对象的唯一性。 它有两种生成方式:一个是默认的1L,比如:private static final long serialVersionUID = 1L;一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:private static final long serialVersionUID = xxxxL;

4. 在写代码时应该从后台开始往前台,还是从前台往后台开始写?

如果对业务不是很熟,则应该从页面的需求开始逐步从action层向service层写。Dao层可以分开,提供一些常用的数据库操作方法,当写到service层,如果dao层提供的方法不能满足条件,然后再在dao层补充相关的方法以供service层使用。但切记不要写完dao层直接写service层,除非对业务非常的熟悉。所以一般情况下,采取从两头向中间写代码比较稳妥。

  • ★★页面转向的方式有下面几种
  1. 当转向的是一个纯粹的页面时,即没有动作请求,不要从后台请求数据,则通过<a href=""/>可以直接转到相应的前台页面,前台页面之间的跳转。如主页面上点击添加用户按钮,页面转向用户添加数据的页面。
  2. 当页面向后台请求一个动作并且传输数据(如:查询或删除)时。要将相关数据提交给后台,然后后台依据该数据形成的条件今进行后台操作,最后返回相应数据至前台页面显示。这种要将数据提交给后台的动作请求,需要用表单进行操作,一般有下面三种方式可以选择。

    <form action="${pageContext.request.conextPath}/queryUser?operation=…" method="post">

    ... <input type="submit" value="添加"/>

    </form>

    <s:form action="user_queryCondition" namespace="/user">

    ... <s:submit value="查询"></s:submit>

    </s:form><!--查询结果数据在本页面显示-->

    <s:url action="user_delUser" namespace="/user" var="url">

    <s:param name="userId" value="#user.id"></s:param>

    </s:url>

    <a href="<s:property value=‘url‘/>">删除</a><!--删除、编辑、修改都可用这种方式-->

  • 利用JSP+Struts2+Mysql技术构建MVC三层框架实现一张数据表的CURD难点
  1. 上传(结合struts2框架)+ 数组形式字段的处理

    UserAction.java】相关字段见下面(2)-(a)

    addUser.jsp

    <s:form action="user_addUser" namespace="/user" enctype="multipart/form-data">

    <s:file name="image" label="照片"></s:file>

    </s:form>

????????UserActionaddUser()

public String addUser(){

//System.out.println(this);//打印到控制台上,验证jsp页面的数据能不能获得

//1.★★单独处理hobby

if(hobbies!=null&&hobbies.length>0){

StringBuffer sb = new StringBuffer();

for(int i=0;i<hobbies.length;i++){

if(i>0)

sb.append(",");

sb.append(hobbies[i]);

}

hobby = sb.toString();

}

//单独处理:filenamestorePathpath

/*2.1★★单独处理filename,上传到文件存储时必须以不同的文件名存储,防止多名用户上传相同文件名文件*/

filename = UUID.randomUUID().toString()+"_"+imageFileName;

//2.2得到存放文件根目录files的真实路径

String storePath = ServletActionContext.getServletContext().getRealPath("/files");

//2.3计算存放的子路径:自动随机生成两级目录

技术分享 path = WebUtil.makeDirs(storePath,filename);

//3.★★文件上传

try {

//common.io包中的:FileUtils.copyFile():拷贝文件到新的文件中并且保存最近修改时间

FileUtils.copyFile(image, new File(storePath+"\\"+path+"\\"+filename));

} catch (IOException e) {

e.printStackTrace();

}

s.addUser(this); //4.user放进去

ActionContext.getContext().put("message", "保存成功!");

return "saveOK";

}

WebUtil.java

public class WebUtil{

public static String makeDirs(String storePath, String filename) {

int hashCode = filename.hashCode();

int dir1 = hashCode&0xf;//最低四位

int dir2 =(hashCode&0xf0)>>4;//其余四位

String newPath = dir1+"\\"+dir2;

File file = new File(storePath,newPath);

if(!file.exists())

file.mkdirs();

return newPath;

}

}

  1. 下载(结合struts2框架)

    下面的方法中利用EL表达式和strutsOGNL表达式进行传值+简单权限拦截

    下面与下载相关的参数说明:

    contentType :内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本text/xml表示XMLimage/gif代表GIF图片,image/jpeg代表JPG图片

    inputName:下载文件的来源流,对应着action类中某个类型为Inputstream的属性名,例如取值为inputStream的属性需要编写getInputStream()方法

    contentDisposition :文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框否则浏览器会尝试直接显示文件。取值为:attachment;filename="struts2.txt",表示文件下载的时候保存的名字应为struts2.txt如果直接写filename="struts2.txt",那么默认情况是代表inline,浏览器会尝试自动打开它,等价于这样的写法:inline; filename="struts2.txt"

    bufferSize:下载缓冲区的大小

    1. UserAction.java

    public class User extends ActionSupport implements Serializable {

    //...其它字段和相应的settergetter 方法

    private String path;//文件保存的路径

    private String filename;//存的文件名 UUID_老文件名

    //文件上传的相关字段

    private File image;

    private String imageFileName;

    private String imageContentType;

    private InputStream inputStream;//文件下载的相关字段:文件下载需要的流

    private UserService s = new UserServiceImpl();

    public String download(){

    技术分享 path = ServletActionContext.getRequest().getParameter("path");

    filename = ServletActionContext.getRequest().getParameter("filename");

    技术分享 String storePath = ServletActionContext.getServletContext().getRealPath("/files");

    try {

    inputStream = new FileInputStream(storePath+"\\"+path+"\\"+filename);//组织路径:构建传输流

    } catch (FileNotFoundException e) {

    e.printStackTrace();

    }

    return SUCCESS;

    }

    }

    1. download.jsp

    <c:url value="/user/download" var="url">

    <c:param name="path" value="${user.path}"></c:param>

    <c:param name="filename" value="${user.filename}"></c:param>

    </c:url>

    <a href="${url}">下载</a>

    1. struts.xml

    <package name="user" namespace="/user" extends="struts-default">

    <action name="download" class="cn.hw.domain.User" method="download">

    <interceptor-ref name="mydefaultstack"></interceptor-ref>

    <!-- 拦截器,登录以后才可以进行下载-->

    <result type="stream" name="success">

    <param name="contentType">application/octet-stream</param>

    <!-- octet-stream表示二进制流? -->

    <param name="inputStream">inputStream</param>

    <!-- 输入是对应的动作类中的那个字段,指定输入流是哪个 -->

    <param name="contentDisposition">attachment;filename=${filename}</param>

    <!-- 要下载的文件名,主要加头attachment,否则会吐到浏览器上面 -->

    </result>

    <result name="login">/login.jsp</result>

    </action>

    </package>

    1. PermissionInterceptor.java】定义拦截器,并在struts.xml中进行配置

    public class PermissionInterceptor implements Interceptor {

    public String intercept(ActionInvocation invocation) throws Exception {

    HttpSession session = ServletActionContext.getRequest().getSession();

    Object obj = session.getAttribute("user");

    if(obj==null){

    return "login";

    }else{

    return invocation.invoke();

    }

    }

    ///其它方法省略

    }

    1. 登录的相关代码和页面等省略

★★JSP+Struts+Mysql构建的MVC三层框架对一张数据表的CURD

标签:

原文地址:http://www.cnblogs.com/heyuchi-2013/p/4322397.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!