struts2中ActionContext和各种Context转化
这里主要来了解struts2的上下文容器:ActionContext。作为struts2执行Action时的上下文,存储了action在执行时需要用到的对象。如我们需要关注的ServletContext,Session, HttpServletRequest ,parameters等。下面是获取这些值的代码
ActionContext ctx = ActionContext.getContext(); //Returns a Map of the ServletContext when in a servlet environment or a generic application level Map otherwise. Map<String, Object> smap = ctx.getApplication(); //struts2的context Map<String, Object> s2map = ctx.getContextMap(); //获取原生的HttpServletRequest HttpServletRequest request = (HttpServletRequest) ctx.get(StrutsStatics.HTTP_REQUEST); //获取请求参数 Map<String, Object> pmap = ctx.getParameters(); //Session Map<String, Object> session = ctx.getSession();
这里我们来关注下ServletContext,在一个spring作为IOC容器的web工程中返回ServletContext信息如下:
org.springframework.web.context.WebApplicationContext.ROOT: org.springframework.web.context.support.XmlWebApplicationContext@1a3ae73: display name [Root WebApplicationContext]; startup date [Tue Jul 10 13:56:33 CST 2012]; root of context hierarchy org.apache.catalina.jsp_classpath:/H:/worksa/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/s2web/WEB- org.apache.jasper.compiler.TldLocationsCache: org.apache.jasper.compiler.TldLocationsCache@13a46b6 org.apache.tomcat.InstanceManager: org.apache.catalina.core.DefaultInstanceManager@65dbe8 contextConfigLocation: classpath:spring.xml javax.servlet.context.tempdir: H:\worksa\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\_ org.apache.tomcat.JarScanner: org.apache.tomcat.util.scan.StandardJarScanner@1563e06 org.apache.catalina.resources: org.apache.naming.resources.ProxyDirContext@1487217
如上,我们可以获取WebApplicationContext:
WebApplicationContext context = (WebApplicationContext) smap.get(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
这样我们就获得了spring的上下文环境,比如我们可以取得bean(虽然大多数时候我们不需要这样做)
DataSource dateSource = (DataSource) context.getBean("dataSource");
如果有需要的话,我们可能更关注servlet参数
//获取请求参数 Map<String, Object> pmap = ctx.getParameters();
这里会获取页面form表单中input的值:包括hidden\text\submit(file除外)等,即便是页面的表单中enctype="multipart/form-data" ,当然这个时候也只能获得非file表单的值。如一个页面表单的值:
age: [Ljava.lang.String;@1715c20 username: [Ljava.lang.String;@14d3b51 query: [Ljava.lang.String;@1575c7e
其实我们知道对于enctype="multipart/form-data" 能够获取到form表单的值,完全得益于
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
及其底层采用的common-fileupload实现
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default" /> <constant name="struts.multipart.handler" value="jakarta" />
但是对于原生的HttpServletRequest来说,如果表单的编码为enctype="multipart/form-data" 就没那么简单了,通常是通过读取Stream的方法并通过解析结果返回,如:
BufferedReader bufferReader = new BufferedReader(request.getReader()); String line = null; StringBuilder buffer = new StringBuilder(); try { while ((line = bufferReader.readLine()) != null) { System.out.println(line); buffer.append(line); } } catch (IOException e) { }
这里顺便介绍下对form表单编码为enctype="multipart/form-data" 时,获取到contentType为
multipart/form-data; boundary=---------------------------265001916915724
后面的boundary是一个不会和文件内容重复的串并通过他把多个文件或者输入域分割开来。如上面的表单会打印
-----------------------------265001916915724 Content-Disposition: form-data; name="age" aaa -----------------------------265001916915724 Content-Disposition: form-data; name="username" 123 -----------------------------265001916915724 Content-Disposition: form-data; name="query" 查询 -----------------------------265001916915724--
注意这里request.getReader()如果getInputStream已经被调用会抛出异常IllegalStateException