关于struts2

来源:互联网 发布:mac 10.12 降级 编辑:程序博客网 时间:2024/05/20 01:45

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 scopeextraContext.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>


0 0