关于struts2

1:struts是将请求和视图分开。


2:这里我下载的是struts 2.3.29,下面有一个blank.war关于struts.xml和web.xml的配置直接在里面找就行了。


3:若要使在myeclipse中出现xml文件提示,window->preference->XML catalog->add,选择url,这里url写的是http://struts.apache.org/dtds/struts-2.3.dtd,location写struts2-core-2.3.29目录下的struts-2.3.dtd所在位置,如图:

这样就会有提示了。


4:关于将包要自己手动从别的文件夹下复制到tomcat webapp下的项目lib中去了,这样有点麻烦,将所需要的包复制到myeclipse的web项目的lib下面,这样发布的时候会自动发布到tomcat下。


5:<constant name="struts.devMode" value="true" />属性是让项目处于开发者模式,更改之后就不用每次都重新启动tomcat了。


6:输入地址:http://localhost:8080/mashibingStruts/hello 后所发生的事情

客户端输入url地址,发送请求,通过http协议发送给tomcat,tomcat通过url地址中的mashibingStruts知道了是要处理这个web application,然后参考这个web application中的web.xml文件,发现里面有一个filter--struts2,这个filter会过滤所有的url地址,然后将这个请求交给org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter来处理。这个类会根据请求的后半部分在struts.xml中来查询package,<package name="default" namespace="/" extends="struts-default">,然后在这个package中查询有没有hello这个action,查到这个action之后再进行接下来的处理,最后将页面反馈给客户端。


7:namespace一般以"/"开头
namespace可以为空,意味着这个package会处理其他所有package处理不了的action。如果这个package也处理不了,就会报错了。

如果直接访问http://localhost:8080/mashibingStruts/,那么就会交给web.xml中的<welcome-file>index.jsp</welcome-file>去处理了。


8:action中的class什么都不写的时候是默认调用ActionSupport的execute方法.

实现ActionSupport接口而不实现Action接口,因为ActionSupport已经为我们实现了Action,而且封装了很多好的方法可以直接调用。


9:struts2中的路径问题是根据action的路径,而不是jsp路径来决定,所以尽量不要使用相对路径,而使用绝对路径。

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

10:Action执行的时候并不一定要执行execute方法,可以再配置文件中配置Action的时候用method=来指定执行哪个方法,也可以在url地址中动态指定(DMI)(推荐),因为前者会产生太多的action。


11:使用通配符可以将配置降到最低,但是一定要遵循“约定优于配置”的原则。


12:当struts2的url传参出现中文乱码时,server.xml文件中的<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"  />修改成:<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"  URIEncoding="utf-8" />即可。但是如果仅仅改的是tomcat中的server.xml不行,因为myeclipse重启的时候会用configuration files中的配置文件将其覆盖,所以应该改configuration files中的server.xml文件。


13:当数据校验时,struts2可以在action中使用addFieldError()方法,将错误信息放到valueStack中,然后用ognl表达式读出来。


访问web元素,向request.session等注入值时

1、可以实现RequestAware,SessionAware接口,实现其中的set方法。(IOC注入思想)

Struts在实例化一个Action实例时,如果发现它实现了相应的Aware接口,会把相应的资源通过Aware接口方法注射进去。这种方式也可以叫做注射方式(IoC方式)。

Servlet API中常用对象application、request、response、Session对应的Aware接口分别为ServletContextAware、ServletRequestAware、ServletResponseAware、SessionAware。实现了这4种接口,能够感知到这些对象

org.apache.struts2.interceptor.ServletConfigInterceptor 这个拦截器会在值执行Action之前,看该Action是否实现了Aware接口,如果实现了aware接口,就会像相应的servlet对象注入进来

public String intercept(ActionInvocation invocation) throws Exception {
	final Object action = invocation.getAction();
	//获得ActionContext,通过ActionContext注入内置对象
	final ActionContext context = invocation.getInvocationContext();

	if (action instanceof ServletRequestAware) {
		HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
		((ServletRequestAware) action).setServletRequest(request);
	}

	if (action instanceof ServletResponseAware) {
		HttpServletResponse response = (HttpServletResponse) context.get(HTTP_RESPONSE);
		((ServletResponseAware) action).setServletResponse(response);
	}

	if (action instanceof ParameterAware) {
		((ParameterAware) action).setParameters((Map)context.getParameters());
	}

	if (action instanceof ApplicationAware) {
		((ApplicationAware) action).setApplication(context.getApplication());
	}
	
	if (action instanceof SessionAware) {
		((SessionAware) action).setSession(context.getSession());
	}
	
	if (action instanceof RequestAware) {
		((RequestAware) action).setRequest((Map) context.get("request"));
	}

	if (action instanceof PrincipalAware) {
		HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
		if(request != null) {
			// We are in servtlet environment, so principal information resides in HttpServletRequest
			((PrincipalAware) action).setPrincipalProxy(new ServletPrincipalProxy(request));
		}
	}
	if (action instanceof ServletContextAware) {
		ServletContext servletContext = (ServletContext) context.get(SERVLET_CONTEXT);
		((ServletContextAware) action).setServletContext(servletContext);
	}
	return invocation.invoke();
}
2、可以用ServletActionContext.getRequest();来获取HttpServletRequest。然后通过HttpServletRequest来获取HttpSession等。

3、可以用actionContext.get("request");来获取HttpServletRequest,actionContext.getContext.getSession();来获取session等。


struts2 doFilter拦截器工作原理时序图:


struts2 关于ActionContext和值栈相关源码:


public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
	HttpServletRequest request = (HttpServletRequest) req;
	HttpServletResponse response = (HttpServletResponse) res;

	try {
		if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
			chain.doFilter(request, response);
		} else {
			prepare.setEncodingAndLocale(request, response);
			//创建ActionContext对象
			prepare.createActionContext(request, response);
			prepare.assignDispatcherToThread();
			request = prepare.wrapRequest(request);
			ActionMapping mapping = prepare.findActionMapping(request, response, true);
			if (mapping == null) {
				boolean handled = execute.executeStaticResourceRequest(request, response);
				if (!handled) {
					chain.doFilter(request, response);
				}
			} else {
				execute.executeAction(request, response, mapping);
			}
		}
	} finally {
		prepare.cleanupRequest(request);
	}
}

public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
	ActionContext ctx;
	//创建值栈对象
	ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
	//把后面的Map赋值到值栈的Map中
	stack.getContext().putAll(dispatcher.createContextMap(request, response, null));
	//把值栈中的Map存储到ActionContext中一份
	ctx = new ActionContext(stack.getContext());

	request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
	ActionContext.setContext(ctx);
	return ctx;
}

public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,
		ActionMapping mapping) {
	//封装了传入的内置对象
	Map requestMap = new RequestMap(request);
	Map params = new HashMap(request.getParameterMap());
	Map session = new SessionMap(request);
	Map application = new ApplicationMap(servletContext);
	//把相应的Map和传入的内置对象交给了createContextMap方法
	Map<String,Object> extraContext = createContextMap(requestMap, params, session, application, request, response);

	return extraContext;
}

public HashMap<String,Object> createContextMap(Map requestMap,
								Map parameterMap,
								Map sessionMap,
								Map applicationMap,
								HttpServletRequest request,
								HttpServletResponse response) {
	//声明的大Map对象,存储了所有的小Map和JSP内置对象,此大Map返回
	HashMap<String,Object> extraContext = new HashMap<String,Object>();
	extraContext.put(ActionContext.PARAMETERS, new HashMap(parameterMap));
	extraContext.put(ActionContext.SESSION, sessionMap);
	extraContext.put(ActionContext.APPLICATION, applicationMap);

	extraContext.put(ActionContext.LOCALE, locale);

	extraContext.put(StrutsStatics.HTTP_REQUEST, request);
	extraContext.put(StrutsStatics.HTTP_RESPONSE, response);
	extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext);

	// helpers to get access to request/session/application scope
	extraContext.put("request", requestMap);
	extraContext.put("session", sessionMap);
	extraContext.put("application", applicationMap);
	extraContext.put("parameters", parameterMap);

	AttributeMap attrMap = new AttributeMap(extraContext);
	extraContext.put("attr", attrMap);

	return extraContext;
}


14:当用了struts2标签的时候<%@taglib prefix="s"uri="/struts-tags"%>,web.xml要改成下面的形式:

<filter-mapping>
              <filter-name>struts2</filter-name>
              <url-pattern>/*</url-pattern>
</filter-mapping>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值