struts工作流程分析

2008.11.23 / 标签: ,,, / 分类: J2EE技术

技术关键在于学习其原理,而不是浅浅淡淡的会用,免得别人问起的时候什么也不知道,尤其是在面试时!
首先页面上的数据请求被发送到服务器,此时的请求先进入到前端控制器(ActionServlet)。ActionServlet再将请求转发给后端控制器(Action),在转发中顺便送了一份礼物form(ActionForm),在Action中对form中的数据做实际的处理操作并返回一份礼物forward(ActionForward)给ActionServlet,ActionServlet收到这份礼物后根据其中的关键字从struts配置文件Struts-config.xml中获取具体的跳转页。
那么ActionServlet是怎么知道该找哪个后端控制器呢?又是怎么知道返回的ActionForward具体是什么呢?为了回答这个问题,我们参考一个用Struts做的登陆程序。

登陆表单代码:

 
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  3. <html>
  4.   <head>
  5.     <title>struts工作流程分析</title>
  6.   </head> 
  7.   <body>
  8.     <form action="login.do" method="POST">
  9.         用户名:<input type="text" name="userName"><br/>
  10.         密码:<input type="password" name="userPwd"><br/>
  11.         <input type="submit" value="登录">
  12.     </form>
  13.   </body>
  14. </html>

 

LoginAction代码:

 
  1. package cn.ineeke.action;
  2.  
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5.  
  6. import org.apache.struts.action.Action;
  7. import org.apache.struts.action.ActionForm;
  8. import org.apache.struts.action.ActionForward;
  9. import org.apache.struts.action.ActionMapping;
  10.  
  11. import cn.ineeke.form.LoginForm;
  12. /**
  13.  *作者:Neeke
  14.  *BLOG:http://www.ineeke.com
  15.  */
  16. public class LoginAction extends Action {
  17.  
  18.     @Override
  19.     public ActionForward execute(ActionMapping mapping, ActionForm form,
  20.             HttpServletRequest request, HttpServletResponse response)
  21.             throws Exception {
  22.             LoginForm loginForm = (LoginForm)form;
  23.             String forwardName = "failure";
  24.             if(loginForm.getUserName().equals("neeke") && loginForm.getUserPwd().equals("123456")){
  25.                 forwardName = "success";
  26.             }
  27.             return mapping.findForward(forwardName);
  28.     }
  29.  
  30. }

LoginForm代码:

 
  1. package cn.ineeke.form;
  2.  
  3. import org.apache.struts.action.ActionForm;
  4.  
  5. public class LoginForm extends ActionForm {
  6.     private String userName = null;
  7.     private String userPwd = null;
  8.     public String getUserName() {
  9.         return userName;
  10.     }
  11.     public void setUserName(String userName) {
  12.         this.userName = userName;
  13.     }
  14.     public String getUserPwd() {
  15.         return userPwd;
  16.     }
  17.     public void setUserPwd(String userPwd) {
  18.         this.userPwd = userPwd;
  19.     }
  20. }

 

Struts-config.xml文件:

 
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd">
  3.  
  4. <struts-config>
  5.   <form-beans>
  6.     <form-bean name="loginForm" type="cn.ineeke.form.LoginForm"></form-bean>
  7.   </form-beans>
  8.   <action-mappings>
  9.     <action path="/login" type="cn.ineeke.action.LoginAction" name="loginForm">
  10.         <forward name="success" path="/success.jsp"></forward>
  11.         <forward name="failure" path="/failure.jsp"></forward>
  12.     </action>
  13.   </action-mappings>
  14.   <message-resources parameter="cn.ineeke.struts.ApplicationResources" />
  15. </struts-config>
  16.  

当我们的表单提交给login.do的时候,ActionServlet就会去读取Struts-config.xml文件并根据<action path="/login" type="cn.ineeke.action.LoginAction" name="loginForm">中的type属性找到具体的后端控制器LoginAction,与此同时又根据name属性找到<form-bean name="loginForm" type="cn.ineeke.form.LoginForm"></form-bean>并将表单中的数据存储在LoginForm的实例中(这个实例就是前端控制器送给后端控制器的礼物了),在LoginAction的execute方法中进行数据处理并返回一个ActionForward对象(回赠一份礼物)给ActionServlet。最后ActionServlet再根据这份礼物的关键字在
<forward name="success" path="/success.jsp"></forward>
<forward name="failure" path="/failure.jsp"></forward>
中进行查找,并跳转到相应的path。

汉字URL编码

2008.10.15 / 标签: ,,,,,, / 分类: J2EE技术

这是本次项目的最后一个问题了,把这个问题解决了,项目就彻底竣工了。先说说要达到的效果:点击一个关键字,使用URL重写传值给Servlet,然后从数据库中查出所有包含这个关键字的文章。
然而在JSP中我们点击这样一个超级链接:http://localhost:8080/wwwroot/tagservlet?tag=数据库
可是这样传递的值我们在Servlet中是没法获取到的,我们需要对这里的汉字进行URL编码,这样我们才能够在Servlet中使用request.getParameter("tag")获得我们传递过来的值。为此,我们需要导入java.net.URLEncoder这个包,接下来使用URLEncoder.encode("数据库")来将“数据库”这三个字进行转码得到的结果是“%CA%FD%BE%DD%BF%E2”,如此一来我们的链接就变为了:http://localhost:8080/wwwroot/tagservlet?tag=%CA%FD%BE%DD%BF%E2
然而,当用request.getParameter("tag")获取这个值并将其输出,你会发现是一堆“?”,这里还得在转码才能得到汉字:
String tag = request.getParameter("tag");
tag = new String(tag.getBytes("ISO-8859-1"),"GBK");
这下终于好了,为什么汉字总是这么麻烦,老要转来转去的,老外的字母就没有问题…

J2EE MVC模式中首页初始化

2008.10.04 / 标签: ,,,,,,, / 分类: J2EE技术

虽然也学了这么久的J2EE了(基础型),但是我一直都搞不明白:MVC模式是要分三层的,显示层、控制层(业务逻辑层)及数据层,业务逻辑层才能访问数据层,而显示层不能够直接访问数据层。既然如此,那么网站的首页所需要的数据都是来自数据库的,是要动态读取的,这就要在jsp中直接访问数据层,岂不是相互矛盾了吗?
去了几个技术论坛看了看,有人说那只是一个高效的框架模型,不一定非要遵守,可以直接在首页jsp中调用数据层的方法,活人岂能被尿憋死?话虽说有那么点道理,不过我还是不想这么试。
我是这么想的:
方法1.能不能打开网站地址时候访问的第一个文件是一个Servlet,在Servlet中获得首页用于显示所需要的所有数据,然后将它放在request中,接着在使用
request.getRequestDispatcher("index.jsp").forward(request, response);
跳转到真实的首页,如此即可在index.jsp中从request中获得所要的数据了。那么,如何才能打开网址就直接访问Servlet呢?在网站的根目录下WEB-INF中的web.xml中有这么一对标签:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
类似于配置IIS中的默认首页 ,我们把这里的index.jsp改为对应的Servlet即可。

方法2.创建一个过滤器,专门用来过滤首页文件,当请求首页文件时就在过滤器中取数据。过滤器本身其实也是Servlet。
我就晕了,无论用这里面哪一个方法,那这里面的Servlet到底属于哪一层啊?是不是我太钻牛角尖了?

如何从Servlet中获取物理路径

2008.10.01 / 标签: ,,, / 分类: J2EE技术
Sofa

有个地方需要用到文件的物理路径,因为我需要调用方法来删除用户上传至服务器的文件。代码如下:

  1. /**
  2. * 用于删除上传的附件
  3. * @param url String
  4. * @return boolean
  5. */
  6. public static boolean deleteUploadFileByUrl(String url)
  7. {
  8. File file = new File(url);
  9. boolean ok = false;
  10. if(file.exists())
  11. {
  12. if(file.delete())
  13. {
  14. ok = true;
  15. }
  16. }
  17. return ok;
  18. }

可是直接传文件的相对路径当然不行啦。起初我想到的是request.getContextPath(),结果返回的是网站的相对根目录,没用,PASS掉!哎~忘了是用哪个了,我记得好像有个Server中的一个方法可以用来获取物理路径,晕~ASP.NET学时间长了,J2EE忘了差不多了…经过我分别对request和response的个个方法逐一查看(速度还是很快的)。终于被我给找到了。
request.getSession().getServletContext().getRealPath(“”);
这样就可以获得网站所在的物理路径了,OK问题解决,继续折腾…

doGet()

2008.04.01 / 标签: / 分类: J2EE技术
Sofa

doGet()

doGet():由服务器调用来处理客户端发出的GET()请求。通过GenericServlet类service()方法来调用此方法。重写GET方法还支持HTTP HEAD请求,该请求返回没有主题只有标题字段的响应。提交响应之前,Servlet容器要编写标题,这是因为在HTTP中必须在发送响应主体之前发送标题。GET方法必须是安全的,如果客户端请求更改存储的数据,则必须使用其他的HTTP方法。如果请求的格式不正确,则doGet()方法会返回HTTP“请求错误消息。doGet()方法的语法为:

public void doGet(HttpServeltRequest req,HttpServletResponse res) throws ServletException,IOException

其中,req是存储客户端请求的HttpServletRequest对象;res是包含服务器对客户端作出响应的HttpSevletResponse对象。

无觅相关文章插件,快速提升流量