Strut2 determines whether it is an AJAX call
1. AJAX and traditional Form forms
In fact, both are generally POST requests via HTTP. The difference is that after the browser submits the Form form, it expects the server to return a complete HTML page. The AJAX call is issued by the XMLHttpRequest object (different browsers may be different). The browser expects the server to return HTML fragments, but there are no requirements for JSON, XML, etc. How to use it after returning to the browser is also determined by the JS script itself.
2. Is the request AJAX
So for the server side, how to determine whether an HTTP request is an AJAX call? This requires the HTTP header.
We can judge by the x-request-with in the header. Although different browsers send AJAX requests different objects, if jQuery uses to send AJAX requests, the identifier has been added when jQuery implements ajax internally. The jQuery source code is as follows: xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
Therefore, if the project's front-end pages send AJAX requests through jQuery, this judgment is safe.
Below is the header information carried by HTTP requests.
Normal Form Form Submission
===MimeHeaders ===accept = */*referer =http://localhost:8080/user2/toQueryPage.actionaccept-language = zh-CNuser-agent = Mozilla/4.0 (compatible; MSIE8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E)accept-encoding = gzip, deflatehost = localhost:8080connection = Keep-Alivecache-control = no-cache
AJAX Call (IE)
===MimeHeaders ===x-requested-with = XMLHttpRequestaccept-language = zh-cnreferer =http://localhost:8080/user2/toQueryPage.actionaccept = application/json, text/javascript,*/*; q=0.01content-type =application/x-www-form-urlencodedaccept-encoding = gzip, deflateuser-agent = Mozilla/4.0 (compatible; MSIE8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E)host = localhost:8080content-length = 57connection = Keep-Alivecache-control = no-cache
3. Obtain HTTP request header in Action
In the Action class, the HttpServletRequest object is obtained through the ServletRequestAware interface, and then the header information we want is obtained through the getHeader method.
public abstract class BaseAction <ParamVo extends BaseParamVo, ResultVo extends BaseResultVo> extends ActionSupport implements ServletRequestAware { private static final String AJAX_RESULT_NAME = "ajaxResult"; private static final String XHR_OBJECT_NAME = "XMLHttpRequest"; private static final String HEADER_REQUEST_WITH = "x-requested-with"; /** * Request object, used to determine whether the request is an AJAX call*/ private HttpServletRequest request; private ParamVo paramVo; private ResultVo resultVo; @Override public String execute() { String resultPage = SUCCESS; try { resultVo = doExecute(paramVo); } catch (BaseException e) { resultPage = ERROR; } if (XHR_OBJECT_NAME.equals(request.getHeader(HEADER_REQUEST_WITH))) { resultPage = AJAX_RESULT_NAME; } return resultPage; } } Struts2 Performance Tuning Interceptor
When we need to achieve certain small needs in our work, we might as well conduct a simple survey to see if the open source framework we are using already has the functions we need, so that we don’t have to repeatedly invent the wheel.
Let’s take performance testing as an example to see how to investigate whether the Struts2 framework has this function.
1. struts-default.xml
Because many of the core functions of Struts2 are implemented based on internal interceptors, we first need to see if it has performance tuning-related interceptors. This requires you to check the default configuration file struts-default.xml in strut2-core-2.3.1.2.jar.
<span style="white-space:pre"> </span><interceptor name="alias"/> <interceptor name="autowiring"/> <interceptor name="chain"/> <interceptor name="conversionError"/> <interceptor name="cookie"/> <interceptor name="clearSession" /> <interceptor name="createSession" /> <interceptor name="debugging" /> <interceptor name="execAndWait"/> <interceptor name="exec"/> <interceptor name="execAndWait"/> <interceptornameinterceptorname="exception"/> <interceptor name="exception"/> <interceptor name="fileUpload"/> <interceptor name="i18n"/> <interceptor name="logger"/> <interceptor name="modelDriven"/> <interceptor name="scopedModelDriven"/> <interceptor name="params"/> <interceptor name="actionMappingParams"/> <interceptor name="prepare"/> <interceptor name="staticParams"/> <interceptor name="scope"/> <interceptor name="servletConfig"/> <interceptor name="timer"/> <interceptor name="timer"/> <interceptor name=" name="token"/> <interceptor name="tokenSession"/> <interceptor name="validation"/> <interceptor name="workflow"/> <interceptor name="store" /> <interceptor name="checkbox" /> <interceptor name="profiling" /> <interceptor name="roles" /> <interceptor name="annotationWorkflow" /> <interceptor name="multiselect" />
Struts2 has many interceptors built in like a treasure chest. You can see that profiling is probably an interceptor that meets our needs. Then open the source code and find out now.
2. ProfilingActivationInterceptor
org.apache.struts2.interceptor.ProfilingActivationInterceptor.java
public class ProfilingActivationInterceptor extendsAbstractInterceptor { private String profilingKey = "profiling"; private boolean devMode; @Inject(StrutsConstants.STRUTS_DEVMODE) public void setDevMode(String mode) { this.devMode = "true".equals(mode); } @Override public String intercept(ActionInvocationinvocation) throws Exception { if (devMode) { Object val =invocation.getInvocationContext().getParameters().get(profilingKey); if (val != null) { String sval = (val instanceof String ?(String)val : ((String[])val)[0]); boolean enable = "yes".equalsIgnoreCase(sval)|| "true".equalsIgnoreCase(sval); UtilTimerStack.setActive(enable); invocation.getInvocationContext().getParameters().remove(profilingKey); } } return invocation.invoke(); } }
From the source code, we can see that as long as the HTTP request parameters sent by the browser include profiling=true or yes, the performance interceptor will turn on the Timer tool class and print out the execution time of the Action.
3. struts.xml
Because the profiling interceptor is not included in the default defaultStack, we must first append it to our custom interceptor stack.
<package name="ajax-default" extends="velocity-default"> <result-types> <result-type name="json"/> </result-types> <interceptors> <interceptor-stacknameinterceptor-stackname="ajaxInterceptorStack"> <interceptor-refnameinterceptor-refname="defaultStack" /> <interceptor-ref name="profiling"/> </interceptor-stack> </interceptors> <default-interceptor-refnamedefault-interceptor-refname="ajaxInterceptorStack" /> <global-results> <result name="comAjaxResult" type="json"> <param name="excludeNullProperties">true</param> <param name="root">result</param> <param name="ignoreHierarchy">false</param> </result> </global-results> </package>
4. userview.js
You can now modify the AJAX call parameters, and then add the profiling parameters to start performance tuning.
function searchAllUser(){ jQuery.ajax({ type:"post", url: "searchAllUser.action", processData:true, dataType:'json', data:jQuery("#userQueryForm").serialize() + "&profiling=yes", success:function(data) { if (data.status == 1) { alert("Create successful"); generateTableFromJson("result", data.resultRows); } else { alert("Create failed"); } } }); }
5. Final effect
The printing result is as follows. In addition to the total execution time, the execution time of the Action method and the rendering time of the Results are listed separately.