


Determine whether to call AJAX in Java's Struts and use interceptors to optimize it
Strut2 Determine whether it is an AJAX call
1. AJAX and traditional Form form
In fact, both are generally POST requests through HTTP. The difference is that after the browser submits the 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 an HTML fragment. Specifically, 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. Whether the request is AJAX
So for the server side, how to determine whether an HTTP request is an AJAX call? This requires looking at the HTTP Header.
We can judge by x-request-with in the Header. Although different browsers send AJAX requests to different objects, if jQuery is used to send AJAX requests, the identifier has been added when jQuery implements ajax internally. The jQuery source code looks like this: xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
So, if the front-end page of the project sends AJAX requests through jQuery, this judgment is safe.
The following is the Header information carried by the HTTP request.
Normal Form form submission
===MimeHeaders === accept = */* referer =http://localhost:8080/user2/toQueryPage.action accept-language = zh-CN user-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, deflate host = localhost:8080 connection = Keep-Alive cache-control = no-cache
AJAX call (IE)
===MimeHeaders === x-requested-with = XMLHttpRequest accept-language = zh-cn referer =http://localhost:8080/user2/toQueryPage.action accept = application/json, text/javascript,*/*; q=0.01 content-type =application/x-www-form-urlencoded accept-encoding = gzip, deflate user-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:8080 content-length = 57 connection = Keep-Alive cache-control = no-cache
##3. Obtained in Action HTTP request header
In the Action class, obtain the HttpServletRequest object through the ServletRequestAware interface, and then obtain the header information we want 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对象,用来判断请求是否是AJAX调用 */ 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; } }
When we need to implement some small requirements at work, we might as well conduct a simple survey first and see Does the open source framework we are using already have the functions we need, so we don’t have to reinvent the wheel?
Let’s take performance testing as an example to see how to investigate whether the Struts2 framework has this function.
<span style="white-space:pre"> </span><interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/> <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/> <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/> <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/> <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/> <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" /> <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" /> <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" /> <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/> <interceptornameinterceptorname="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/> <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/> <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/> <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/> <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/> <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/> <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/> <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/> <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/> <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/> <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/> <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/> <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/> <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/> <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/> <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/> <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" /> <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" /> <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" /> <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" /> <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" /> <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />
2. ProfilingActivationInterceptor
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 source code As can be seen in , as long as the HTTP request parameter sent by the browser contains profiling=true or yes, the performance interceptor will open the Timer tool class and print out the execution time of the Action.
<package name="ajax-default" extends="velocity-default"> <result-types> <result-type name="json" class="org.apache.struts2.json.JSONResult"/> </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>
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("创建成功"); generateTableFromJson("result", data.resultRows); } else { alert("创建失败"); } } }); }
5. The final effect
The printed result is as follows. In addition to the total execution time, the execution time of the Action method and the rendering time of the Result will be listed separately.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics





This article analyzes the top four JavaScript frameworks (React, Angular, Vue, Svelte) in 2025, comparing their performance, scalability, and future prospects. While all remain dominant due to strong communities and ecosystems, their relative popul

This article addresses the CVE-2022-1471 vulnerability in SnakeYAML, a critical flaw allowing remote code execution. It details how upgrading Spring Boot applications to SnakeYAML 1.33 or later mitigates this risk, emphasizing that dependency updat

Node.js 20 significantly enhances performance via V8 engine improvements, notably faster garbage collection and I/O. New features include better WebAssembly support and refined debugging tools, boosting developer productivity and application speed.

The article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra

Java's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa

This article explores methods for sharing data between Cucumber steps, comparing scenario context, global variables, argument passing, and data structures. It emphasizes best practices for maintainability, including concise context use, descriptive

This article explores integrating functional programming into Java using lambda expressions, Streams API, method references, and Optional. It highlights benefits like improved code readability and maintainability through conciseness and immutability

Iceberg, an open table format for large analytical datasets, improves data lake performance and scalability. It addresses limitations of Parquet/ORC through internal metadata management, enabling efficient schema evolution, time travel, concurrent w
