struts2的请求编码和valuestack放在哪了
首先来看一下Struts2的过滤器的doFilter方法
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
prepare.setEncodingAndLocale(request, response);
prepare.createActionContext(request, response);
prepare.assignDispatcherToThread();
if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);
} else {
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);
}
}
首先我们来分析一下struts2的请求参数的编码,看一下这个方法。 prepare.setEncodingAndLocale(request, response);从字面意思来看,这个就是设置encoding和locale,当然咯,说话要讲究实际,我们还是去看一下源代码。
public void setEncodingAndLocale(HttpServletRequest request, HttpServletResponse response) {
dispatcher.prepare(request, response);
}
这里调用了dispatcher.prepare()方法,这里我们继续跟下,进入prepare方法
public void prepare(HttpServletRequest request, HttpServletResponse response) {
String encoding = null;
if (defaultEncoding != null) {
encoding = defaultEncoding;
}
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
encoding = "UTF-8";
}
Locale locale = null;
if (defaultLocale != null) {
locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
}
if (encoding != null) {
applyEncoding(request, encoding);
}
if (locale != null) {
response.setLocale(locale);
}
if (paramsWorkaroundEnabled) {
request.getParameter("foo"); // simply read any parameter (existing or not) to "prime" the request
}
}
这里我们先看一下这个defaultEncoding。
/**
* Store state of StrutsConstants.STRUTS_I18N_ENCODING setting.
*/
private String defaultEncoding;
好像貌似这里可以通过default.properties中的属性注入进来的。
default.properties里面有这么一条struts.i18n.encoding=UTF-8,说明编码为utf-8,当然我们可以修改这个变量,我们可以在在struts.xml中添加constant节点修改,name=struts.i18n.encoding,value=编码。
说完了这里,去看一下applyEncoding(request, encoding)这个方法。
private void applyEncoding(HttpServletRequest request, String encoding) {
try {
if (!encoding.equals(request.getCharacterEncoding())) {
// if the encoding is already correctly set and the parameters have been already read
// do not try to set encoding because it is useless and will cause an error
request.setCharacterEncoding(encoding);
}
} catch (Exception e) {
LOG.error("Error setting character encoding to '" + encoding + "' - ignoring.", e);
}
}
这里request.setCharacterEncoding(encoding);发现设置post方式请求的编码。
到此,请求参数的编码到此完毕。
下一步,寻找valuestack放在哪了?
还是来到struts2的过滤器的doFilter方法中,我们去看一下execute.executeAction(request, response, mapping);这一条代码
public void executeAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
dispatcher.serviceAction(request, response, servletContext, mapping);
}
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException {
Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
boolean nullStack = stack == null;
if (nullStack) {
ActionContext ctx = ActionContext.getContext();
if (ctx != null) {
stack = ctx.getValueStack();
}
}
if (stack != null) {
extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
}
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
}
上述贴出了部分代码,我们需要的是 request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());可以发现是将valuestack放入了request对象中了
到此,源码解析结束