`
tianhandigeng
  • 浏览: 368671 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

项目开发全纪录(四)

阅读更多

31、修改Action类后,不用重启Tomcat也能重新加载的方法
参考:
公司的几个人都装的myeclipse6.5的集成版本。但有的电脑就是要重启tomcat才能生效修改的action类。
 今天终于让人找到解决的办法:呵呵!
1.在http://www.eclipsetotale.com/tomcatPlugin.html 去下载一个tomcatPluginV321插件,注意要选择正确的版本。
2.装eclipse插件,不用我多说,直接解压到插件目录。
3.打开myeclipse 在window-》preferense->tomcat配置tomcat信息。
4.将插件中的DevLoader.zip 将成DevLoader.jar ,把这个包直接放在tomcat安装目录下common/lib目录
这样就ok了,
注意:
  1.  tomcat起动方式是debug模式。
  2.对于我装了myeclipse6.5,都不用装插件,直接将DevLoader.jar放下tomcat下的lib目录

 

32、Action是如何获得参数的?
   Struts 2用户处理用户请求的Action实例,并不是用户实现的业务逻辑控制器,而是Action代理----因为用户实现的业务逻辑控制器并没有与Servlet API耦合,显然无法处理用户请求.而Struts 2框架提供了系列拦截器,该系列拦截器负责将HttpServletRequest请求中的请求参数解析出来,传入到Action中,并回调Action的execute方法来处理用户的请求.
   显然,上面的处理过程是典型的AOP处理方式.
   用户实现的Action类仅仅是Struts 2的Action代理的代理目标.用户实现的业务控制器则包含了对用户请求的处理.用户的请求数据包含在HttpServletRequest对象里,而用户的Action类无需访问HttpServletRequest对象.拦截器负责将HttpServletRequest里的请求数据解析出来,并传给逻辑组件Action实例.

 

33、Request对象的getRemoteAddr()方法
   在开发过程中使用request对象的getRemoteAddr()方法时,返回的是0:0:0:0:0:0:0:1,而不是127.0.0.1(回送地址,指本地机,一般用于测试)。那为什么返回的不是我们看到的127.0.0.1呢?实际上0:0:0:0:0:0:0:1是IPv6协议的表示形式,而127.0.0.1是IPv4的表示形式。用于我用的是Win7操作系统,它支持IPv6,所以显示的时候就用IPv6显示出来了,解决的办法是找到C:\Windows\system32\drivers\etc\ hosts这个文件,如果看到是这样
# localhost name resolution is handled within DNS itself.
#    127.0.0.1       localhost
#       ::1             localhost
那就把上面一个的“#”去掉,如果下面一个没有“#”,那么就加上。

 

33、Struts 2中的ActionContext何ServletActionContext
   Struts 2的Action并未直接与任何的Servlet API耦合,这是Struts 2的一个改良之处,因为Action类不再与Servlet API耦合,从而能够更轻松地测试该Action。
   但对于Web应用的控制器而言,不访问Servlet API几乎是不可能的,例如跟踪HTTP Session状态等。Struts 2 框架提供一种更轻松地方式访问Servlet API。Web应用中通常需要访问的Servlet API就是HttpServletRequest、HttpSession和ServletContext,这三个类分别代表JSP内置对象中的request、session和application。

Struts 2提供了一个ActionContext类,Struts 2的Action可以通过该类来访问Servlet API。
 ServletActionContext继承ActionContext,它提供了直接与Servlet容器交互的路径。
ActionContext和ServletActionContext有着一些重复的功能,在我们的Action中,该如何去抉择呢?我们遵循的规则是:如果ActionContext能够实现我们的功能,那最好就不要使用ServletActionContext,让我们的Action尽量不要直接去访问Servlet相关的对象。
注意:在使用ActionContext时有一点要注意: 不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许没有 设置,这时通过ActionContext取得的值也许是null;同样,HttpServletRequest req = ServletActionContext.getRequest()也不要放在构造函数中,也不要直接将req作为类变量给其赋值。至于原因,我想是因 为前面讲到的static ThreadLocal actionContext = new ActionContextThreadLocal(),从这里我们可以看出ActionContext是线程安全的,而 ServletActionContext继承自ActionContext,所以ServletActionContext也线程安全,线程安全要求每 个线程都独立进行,所以req的创建也要求独立进行,所以ServletActionContext.getRequest()这句话不要放在构造函数 中,也不要直接放在类中,而应该放在每个具体的方法体中(eg:login()、queryAll()、insert()等),这样才能保证每次产生对象 时独立的建立了一个req。
struts2中获得request、response和session
(1)非IoC方式
方法一:使用org.apache.struts2.ActionContext类,通过它的静态方法getContext()获取当前Action的上下文对象。
ActionContext ctx = ActionContext.getContext();
ctx.put("liuwei", "andy"); //request.setAttribute("liuwei", "andy");
Map session = ctx.getSession(); //session
HttpServletRequest request = ctx.get(org.apache.struts2.StrutsStatics.HTTP_REQUEST);
HttpServletResponse response = ctx.get(org.apache.struts2.StrutsStatics.HTTP_RESPONSE);
细心的朋友可以发现这里的session是个Map对象, 在Struts2中底层的session都被封装成了Map类型. 我们可以直接操作这个Map对象进行对session的写入和读取操作, 而不用去直接操作HttpSession对象.
方法二:使用org.apache.struts2.ServletActionContext类
public class UserAction extends ActionSupport {
    
    //其他代码片段
    
    private HttpServletRequest req;
// private HttpServletRequest req = ServletActionContext.getRequest(); 这条语句放在这个位置是错误的,同样把这条语句放在构造方法中也是错误的。
    public String login() {
        req = ServletActionContext.getRequest(); //req的获得必须在具体的方法中实现
        user = new User();
        user.setUid(uid);
        user.setPassword(password);
        if (userDAO.isLogin(user)) {
            req.getSession().setAttribute("user", user);
            return SUCCESS;
        }
        return LOGIN;
    }
    public String queryAll() {
        req = ServletActionContext.getRequest(); //req的获得必须在具体的方法中实现
        uList = userDAO.queryAll();
        req.getSession().setAttribute("uList", uList);
        return SUCCESS;
    }
    
    //其他代码片段
}
(2)IoC方式(即使用Struts2 Aware拦截器)
要使用IoC方式,我们首先要告诉IoC容器(Container)想取得某个对象的意愿,通过实现相应的接口做到这点。
public class UserAction extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware {
    private HttpServletRequest request;
    private HttpServletResponse response;
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }
    public void setServletResponse(HttpServletResponse response) {
        this.response = response;
    }
public String execute() {
        HttpSession session = request.getSession();
        return SUCCESS;
    }
}

 

34、JSP文件中charset和pageEncoding的区别
在写JSP文件的时候经常要制定page属性,其中就有charset和pageEncoding的设置,那么这两个到底有什么区别呢?
charset
首先来讲一下charset,我以前一直认为,charset与页面之间参数的传递的编码方式有关,其实这是错的,charset只与页面的显示有关。当服务器向客户端展示页面的时候,这个时候就要用到这个指定的charset
我们在jsp中这样设置:
<%@ page language="java" contentType=”text/html;charset=gbk”%>
现在来看一看jsp文件被编码后生成的Servlet源文件:
try {
      response.setContentType("text/html;charset=gbk");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                  null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;
     …..
   }
蓝色的哪行字就是我们上面设置而起的效果
现在来看看setContentType()这个方法的作用:
setContentType
void setContentType(String type)
Sets the content type of the response being sent to the client, if the response has not been committed yet. The given content type may include a character encoding specification, for example, text/html;charset=UTF-8. The response's character encoding is only set from the given content type if this method is called before getWriter is called.
This method may be called repeatedly to change content type and character encoding. This method has no effect if called after the response has been committed. It does not set the response's character encoding if it is called after getWriter has been called or after the response has been committed.
Containers must communicate the content type and the character encoding used for the servlet response's writer to the client if the protocol provides a way for doing so. In the case of HTTP, the Content-Type header is used.
现在就一目了然了,所以这个charset只与显示有关。

PageEncoding
现在来说说pageEncoding,再说之前,来看看jsp的编码过程。总的来说有三个过程:

第一阶段:JSP-.java
   这个阶段,会根据pageEncoding的设定读取JSP,结果是由指定的pageEncoding的JSP翻译成统一的UTF-8 的JAVA源码(.java),如果pageEncoding设定错了,或没设定(默认ISO8859-1),出来的这个阶段就已是中文乱码。
第二个阶段:JAVA源码到JAVA 字节码(.class),
   不论JSP的编码方式是什么,经过阶段一全部变为了utf-8的Java源码,JAVAC用utf-8的Encoding读取源码,编译成UTF-8二进制码。
第三阶段:TOMCAT载入和执行
   阶段二得来的Java二进制码,被TOMCAT载入后执行显示在客户端,这时一早隐藏在阶段一和阶段二的contentType就发挥作用了。

总之一个的意思是“按这样的字符集表示”,一个是“按这样的指定编码”

 

35、Struts 2配置文件解决乱码问题
   乱码问题在项目的开发过程中经常遇到,这不,这次我又遇到了。描述一下我的项目中的编码。
   我项目中jsp文件的pageEncoding为gbk
   通过表单提交,将内容提交给Action后,中文显示的是?????,为什么是这样呢,原因是这样的,我们可以把Action想象为一个Servlet,我们将数据传给这样的一个servlet,传递的参数按pageEncoding指定的编码方式进行编码,我设的pageEncoding是gbk,为什么还是会显示不出来呢,我的Struts 2 的配置文件有一项是这样设的:
   <constant name="struts.i18n.encoding" value="utf-8" />
当设置该参数为GBK时,相当于执行了HttpServletRequest的setCharacterEncoding(“utf-8”)方法,也就是说我们设了两次编码,这样就乱了。
   所以说在实际的开发过程中,最好的是所有的编码方式都设为一样的,这样才不会出错。

 

36、JSP中用${}无法取值
   项目中jsp页面从Action中取值,用<s:property />可以取得,但是用${}却无法取得。之所以可以用${}来取值,是因为Action中的属性属于ValueStack根对象的属性。用<s:debug/>查看后发现,ValueStack中有值,那为什么就不能取到值呢?之后弄了一下,找到了原因:
   表达式语言(EL)在JSP2.0以后版本中引进,因而要求使用环境为支持JSP2.0(Servlet 2.4)以上版本的应用服务器。我用的是Tomcat 6.0,所以当然符合,最后发现是我设置了“禁止解析表达式语言”,我是在web.xml中禁止的:

<jsp-config>
		<jsp-property-group>
			<description>jsp encoding example</description>
			<display-name>JSPConfiguration</display-name>
			<url-pattern>*.jsp</url-pattern>
			<el-ignored>true</el-ignored> 
			<page-encoding>gbk</page-encoding>
			<scripting-invalid>false</scripting-invalid>
		</jsp-property-group>
		<jsp-property-group>
			<description>html encoding example</description>
			<display-name>JSPConfiguration</display-name>
			<url-pattern>*.html</url-pattern>
			<el-ignored>true</el-ignored>
			<page-encoding>gbk</page-encoding>
			<scripting-invalid>false</scripting-invalid>
		</jsp-property-group>
	</jsp-config>

 因为禁止解析表达式语言,当然就没办法解析后显示了.去掉蓝色的字样就行了。

 

37、“/”在项目中的作用
   在项目开中,经常会看到“/”这个符号,用到这个符号说明用的就是相对路径,
在做邮件链接激活的时候,我第一次写的时候写成这样:
String url=http://localhost:8080/zuwoba/account/activation?code=***
这里我就写成了绝对路径了,结果自己也意识到了这样写成绝对的不行,如果端口号、项目名改了以后,不就麻烦了吗?最好经过思考,觉得还是要相对路径才行,最后我写成了这样:
String url=”/account/activation?code=***”
同样能达到相同的效果,这里就引出来下面我要说的内容:
“/”在项目中的作用,这里列出几种情况
在xml配置文件中用”/”,跟上面一样,指的也是根目录
在jsp中使用,这里就不是只根目录了指的是http://localhost:8080/

  关于是使用相对路径还是绝对路径,我谈谈我个人的见解,在JSP中可以使用绝对路径,在java源文件或其他的文件中不要使用,之所以在JSP中可以使用绝对路径,那是因为用的时候也不是说就是静的,它还是动的,因为我们是这样得到的:

String path = request.getContextPath();
String  basePath = request.getScheme()+"://"+request.getServerName()+":"+
request.getServerPort()+path+"/";

 

 

38、Spring如何读取属性文件
      我们知道可以通过java.util.Properties的load(InputStream inStream)方法从一个输入流中加载属性资源。Spring提供的PropertiesLoaderUtils允许用户直接通过基于类路径的文件地址加载属性资源。下面是例子:

import java.util.Properties;

import org.springframework.core.io.support.PropertiesLoaderUtils;

/** 
 * @project_name   zuwoba
 * @file_name     PropertiesLoaderUtils.java
 * @author        tianhandigeng
 * @version       Oct 21, 2010 1:34:50 AM 
 * @declaration   
 */
public class PropertiesLoaderUtil{
     public static void main(String[] args) throws Throwable{
    	 Properties props=PropertiesLoaderUtils.loadAllProperties("log4j.properties");
    	 System.out.println(props.getProperty("log4j.appender.stdout"));
     }
}
 

39、JQuery实现倒计时跳转
例子:

<!-- JQuery实现倒计时自动跳转 -->
<script>
     var id=setInterval(function (){
         var i=parseInt($('#verify-countdown').text())-1;
         $('#verify-countdown').text(i);
         if(i==0){
            clearTimeout(id);
            window.location="vote/redirectVote";
         }
      },1000);
</script>

 当然了,在使用之前要导入jquery.js文件

 

40、JSP禁止页面后退

<!-- 禁止页面后退 -->
<%
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-store");
response.setDateHeader("Expires", -1);
%>
 

 

 

------未完待续--------

2
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics