Generate Web Output in Multiple Formats and Languages with StrutsCX

Generate Web Output in Multiple Formats and Languages with StrutsCX

s an open source add-on for the Apache Jakarta Struts Framework (or Struts), StrutsCX has its roots in a pure XML- and XSLT-based, multi-language and multi-layout project. With StrutsCX you can easily generate different output formats like HTML, XML, or PDF using standardized XML and XSL technologies. Struts serves as the ideal server technology to perform these XSLT transformations.

StrutsCX also enables you to save and output content in different languages and encodings. Handling information in English, German, French, Spanish, and Italian?as well as in Chinese, Korean, Arabic, Russian, and any other language in the world?is simple with StrutsCX.

A Quick Struts Refresher
Struts encourages application architectures based on the Model 2 approach, a variation of the classic Model-View-Controller (MVC) design paradigm. The great thing about the MVC design pattern is the relative independence it allows between the Model, View, and Controller. Struts processes all incoming HttpServletRequests in one central point, the Controller, where the ActionServlet, the ActionMapping, and several Action classes are assembled. The ActionServlet dispatches all the incoming HttpServletRequests to one of the Action classes. The ActionMapping object, which you can control through the struts-config.xml file, informs the ActionServlet to which class it should dispatch.

Figure 1: Communication Steps Between the Struts Model, View, and Controller

Figure 1 illustrates the Controller’s function: mediating between the Client, the View, and the Model. Only the Controller knows about the Model and the View, it sits between them like a switch. Neither the Model nor the View know about each other. The consequent separation of Model, View and Controller is essential for the successful use of Struts.

Author’s Note: You should place all the controller logic your application needs inside the Action class. You can communicate with the other layers of your Web or J2EE application from there. Although you’re able to also keep business logic in your Controller, it’s a good practice to keep it out of there. Use the components of the Model for this practice, because they are where the actual handling of your data takes place. Saving your data in a database should be a practice that’s part of the Model, too.

Once the Controller is done with a HttpServletRequest, it forwards it to the View. The View’s only job is the graphical presentation of data, for which Struts generally uses JavaServer Pages (JSP) inside the View.

In Struts, all communication between the Controller and the View takes place indirectly via the HttpServletRequest, HttpSession, and the ServletContext, and no technique is better suited to handle these then servlets. Struts categorically forwards the HttpServletRequest to a servlet. The Servlet Container automatically transforms JSP into servlets as well.

The Limits of Struts and JSP
Struts is expressly open to other View technologies besides JSP. So using alternative techniques for the Struts View starts with thinking about how to replace JSP with other servlet technologies, such as XSLT or an XSLT transformation managed by a servlet.

Figure 2 outlines the use of JSP within the Struts framework. The view is made out of JSP Custom Tag Libraries and the JSP, which use the Tags themselves. The ActionForm classes are JavaBean-like ValueObjects with setter and getter methods. They save the client’s state. In the Struts MVC concept, the ActionForms are located somewhere between the View and the Controller. Struts offers a whole set of specialized Tags you can use to access data in the ActionForms from inside your JSP.

Figure 2: The Struts Architecture

JSP facilitate Java Web programming very well. Together with the Tag Libraries, they provide a wide range of robust tools for the development of the presentation layer in Web or J2EE applications. However, JSP have some drawbacks:

  • Programmers can put application logic inside their JSP. JSP should be used solely to display data graphically. Otherwise, programs can easily become complex and unmanageable.
  • JSP are not 100 percent XML compatible. JSP cannot guarantee that their output will be 100-percent, well-formed XML. In this new era of myriads of XML-consuming Internet access devices, this can be quite a problem.
  • During development, each change made to a JSP forces the Servlet Container to re-translate it into a servlet. With some servlet engines, this leads to annoying delays during development.
  • Accomplishing a pipeline for the View is more complex. Separation of Layout and Style is not as natural as it is when using XSLT.How XSLT Fits In
    XSLT is an official W3C standard for a flexible and powerful language that transforms the structure of XML data into text, PDF, HTML/XHTML, WML, VoiceXML, or any other XML format. An XSLT processor like Xalan or Saxon actually performs the transformation by using an XSL Stylesheet, which itself is an XML document (see Figure 3).

    You define rules for the transformation of your XML data inside the XSL Stylesheet. The XSLT processor uses these rules during transformation. You also can use XPath expressions inside your XSL Stylesheet to select parts of your XML document in a compact manner.

    Figure 3: Principle of XSLT Transformation

    The basic concept behind XSLT/XPath is to separate XML data from its presentation. The same data can easily be presented in different forms and formats to suit different output devices. All the while, the input XML document stays unchanged. For each additional output format you just define another XSL Stylesheet. For a Struts application, this means you can:

  • Represent all your data in the form of an XML document
  • Transform this document (with the help of an XSL Stylesheet) into any data format you like
  • Of course you can generate your XML document in memory; it’s not necessary to work with physical files. You can create the XML document as a Java object and hand it directly to the XSLT processor, which enhances performance incredibly.

    StrutsCX: Struts with XSLT
    StrutsCX combines the elegance of Struts with the power of XSLT. StrutsCX replaces the JSP of the View with XSLT while leaving the Controller and the Model part of Struts untouched.

    Figure 4 illustrates the differences between Struts and StrutsCX. In the View, StrutsCX does not forward to a JavaServer Page but to a servlet, which organizes the construction of an XML-Output-Document object as well as the transformation of this object with an XSL Stylesheet. If an ActionForm Bean is present, the Action copies it to the HttpServletRequest, which is also added to the XML-Output-Document. Similar to Struts, the job of the StrutsCX Action is to mediate between the presentation tier and the other tiers of the Web or J2EE architecture, the business and integrations tiers.

    Figure 4: The StrutsCX Architecture

    StrutsCX behaves differently than Struts in the following aspects:

  • In the View, StrutsCX uses XSLT instead of JSP.
  • Internationalization is not realized through the Java Resource Bundle technique but through a pure XML solution.
  • StrutsCX does not need any Tag Libraries to present error messages. It uses W3C standards like XML and XSLT/Xpath instead.
  • Despite their differences, you can use StrutsCX in parallel with your existing Struts application. StrutsCX merely abandons some of the standard Struts features and replaces them with XML, XSLT, and XPath. The StrutsCXServlet
    As Figure 5 shows, in StrutsCX, the XSLT transformation process is organized through the StrutsCXServlet and its helper classes, StrutsCXDocumentBuilder and StrutsCXTransformer. The StrutsCXServlet controls transformations by:

    1. Creating an XML document with the help of the StrutsCXDocumentBuilder
    2. Forwarding this document to the StrutsCXTransformer for transformation purposes
    Figure 5: The StrutsCXServlet

    The StrutsCXDocumentBuilder gets the information it needs to generate the XML-Output-Document through the HttpServletRequest, the HttpSession, and the ServletContext. All of these are handed over to the one and only public method, createDocument(). The Struts Action checks for the wanted information in the HttpServletRequest, the HttpSession, or the ServletContext, depending on which is best suited to keep the information. The virtual XML-Output-Document that the StrutsCXDocumentBuilder creates contains the following information:

  • The data of the integration tier?this could be database data, data from Enterprise JavaBeans, or data directly out of flat XML files
  • An (optional) ActionForm Bean with the state of the client
  • An (optional) ActionErrors object with the Struts error messages
  • The StrutsCX-Resource-Properties, which under StrutsCX replace the Java Resource Bundles
  • The data of the HttpServletRequest
  • The data of the HttpSession
  • To create the XML-Output-Document use JDOM.

    In StrutsCX, the values of each dataset can be presented to the StrutsCXServlet as an XML object or as a JavaBean. If you choose the latter, you need to add one or more JavaBeans to an ArrayList object, which is then passed to the StrutsCXDocumentBuilder via the HttpServletRequest. The StrutsCXDocumentBuilder uses its helper class StrutsCXBeanToElement to automatically create XML Elements out of the JavaBean’s data and add it to the XML-Output-Document (see Figure 6).

    Figure 6: The XML-Output-Document

    This helper class is based loosely on its archetype, Model 2X, a project quite similar to StrutsCX that Julien Mercay and Gilbert Bouzeid developed. It analyzes the content of each JavaBean with the help of the Java Reflection API and the Java BeanInfo interface. It generates the XML Element out of the name and value of the JavaBean setter and getter methods.

    In much the same way, StrutsCX serializes data out of the ActionForm object with its setters and getters, the HttpServletRequest, the HttpSession, as well as the ActionErrors object with its error messages. I’ll discuss the StrutsCX error handling a little later.

    The StrutsCX-Resources-Properties are XML files that are analogous to the Struts ApplicationResourses.properties. You should provide one for each language in which you want to present your application. It should contain all the internationalized text strings you need in your presentation, besides the data of the integration tier. Other than the ActionForm and the ActionErrors, the StrutsCX-Resources-Properties should not be transferred to the StrutsCXServlet via the HttpServletRequest. Instead, use the ServletContext just once at the start of the Servlet Container, right after the first call of one of the Action classes. This ensures better performance.

    The StrutsCXTransformer does the actual XSL transformation. This class encapsulates the whole transformation process by using JAXP, the Java API for XML Parsing?which is incredibly cool because it abstracts from the de facto XSLT processor you use. Of course you have to provide a proper XSL Stylesheet too, which should likewise be selected by the Action class and added to the HttpServletRequest. The StrutsCXTransformer reads and parses this XSL Stylesheet just in case it was changed since the last call. It uses its helper class StrutsCXURIResolver, which automatically converts relative URIs into absolute URIs.

    The StrutsCXTransformer also offers some practical goodies to make your life easier. For instance, if you’d like to send the XML-Output-Document directly to the HttpServletResponse, add the following parameter to the HttpServletRequest:

    debugxml=true

    This feature is very convenient for the development of XSL Stylesheets and looks great in the newest versions of Internet Explorer and Netscape/Mozilla, in which you can open and close whole XML Element sets.

    If you’d like to disburden your Web server and have the client do the XSLT transformation, you can set another parameter to the HttpServletRequest:

    xsl_clientside=true

    The StrutsCXDocumentBuilder adds a Processing Instruction to the XML-Output-Document with a pointer to the location of your XSL Stylesheet. This document is sent directly to the client’s browser. No server-side transformation takes place.

    As mentioned before, StrutsCX rejects the Java Resource Bundle technique and uses the StrutsCX-Resource-Properties, simple XML files to save text strings for internationalized Web applications. Similar to Struts, StrutsCX can select the appropriate file during runtime by checking the java.lang.Locale object. StrutsCX-Resource-Properties result in quite a lot advantages for you:

  • Besides using the Java Resource Bundle, you can check the consistency of your properties file by providing a DTD or an XML Schema.
  • Like always in XML, you can organize the content hierarchically:
          ...    Tag    ...    ...
  • Inside the XSL Stylesheets, you can easily gain access to these values by using W3C standard XSLT/XPath expression instead of a JSP-Tag:
  • XML uses UTF-8 as standard encoding and offers access to letters in all languages. The StrutsCX-Resources-Properties benefits from this.
  • The StrutsCX Resources-Properties can be filed outside the classpath. Like all the files you like to hide from direct access via HTTP, it’s best to put them somewhere inside the /WEB-INF folder.
  • Translators can use modern XML Editors to edit comfortably the content of the XML files (see Figure 7). There is no similar feature when editing the Java Resource Bundles.
  • In StrutsCX all configuration files are XML based. There is no mix of Java properties and XML properties like you have in Struts.
  • Figure 7: Simple Editing of the StrutsCX Resources-Properties

    Note that the StrutsCX-Resources-Properties should be read into the ServletContext as an org.jdom.Document object the first time one of your Action classes is called. StrutsCX learns where to find them from the strutscx-config.xml, the special StrutsCX configuration file. Therefore inside the web.xml, the initialization parameter to read in the Resource Bundles is obsolete. Error Handling with StrutsCX
    StrutsCX controls the validation of input errors exclusively inside the Action class. The settings in the ActionMapping conform more or less with the ones in Struts. Inside the ActionForm object, nothing really changes. If errors occur, the validate() method returns an ActionErrors container filled with ActionError objects. However, the method add() of the ActionErrors object does need a Struts ActionMessage object (see Figure 8). Although StrutsCX does not use this object, it is added:

    // code-snipped of Struts FormBean:public ActionErrors validate(    ActionMapping mapping,     HttpServletRequest request) {  ActionErrors errors = new ActionErrors();  if (title == null || title.length() < 1) {    errors.add("title", // name of input field    new ActionError("anything")); // anything  }  return errors;}
    Figure 8: The Examination of the ActionErrors Container

    By calling the validate() method of the ActionForm object, the Action class gets hold of the ActionErrors container with its ActionError objects:

    // code-snipped of Struts Action:ActionErrors errors =     actionForm.validate(mapping, request);

    If it's filled, the ActionErrors container will be added to the HttpServletRequest and forwarded to the ERROR target defined inside the struts-config.xml. If the ActionErrors container is empty, the HttpServletRequest gets forwarded to the SUCCESS target defined inside the struts-config.xml:

    // Action code continued:if (!errors.empty()) {  request.setAttribute("errors", errors);  forward = "ERROR";} else {  forward = "SUCCESS";}

    Of course, additional ActionError objects can be added to the ActionErrors container inside the Action classes. There is no restriction to the validation of user input. During XSLT transformation, all these error objects become incorporated into the XML-Output-Document so they can be used by the XSL Stylesheet. Here's an extract from of an XML-Output-Document:

      ...    ...              Please insert a title!      ...        ...    ...            ...  </errors>  ...</root></code></pre>
    <p>Inside the XSL-Stylesheet this information can be used to compose an appropriate error message: </p>
    <pre><code><!-- show error message if error tag present --><xsl:if test="/root/errors/title = node()">  <div class="error">    <xsl:value-of    select="/root/variables/.../errors/title"/>  </div></xsl:if><textarea name="title" rows="2" cols="30"           style="width=250px">  <xsl:value-of select="title"/></textarea></code></pre>
    <p>Coding the XSL Stylesheet is very similar to using a JSP Tag: the goal is to show the error message just in case the <code>xsl:if</code> statement is true, which means an error Element exists inside the XML-Output-Document (see <a href="javascript:showSupportItem('figure9')">Figure 9</a>). An XPath Node Test does the validation. The text of the error message is part of the XML-Output-Document too, and this text automatically gets serialized into it with content from an appropriate StrutsCX-Resources-Properties file. </p>
    <table border="0" cellspacing="0" cellpadding="5">
    <tr>
    <td valign="top"><a href="javascript:showSupportItem('figure9')"><img decoding="async" border="0" alt="" src="/assets/articlefigs/5156.gif"></a></td>
    <td width="12"> </td>
    </tr>
    <tr>
    <td class="smallfont"><a href="javascript:showSupportItem('figure9')">Figure 9</a>: Multi-language Error Messages with StrutsCX</td>
    </tr>
    </table>
    <p><strong>The Advantages of Doing It the StrutsCX Way</strong><br />Using XSLT in the Struts View has the following benefits:</p>
    <li><strong>The whole Web application gets rid of all the JSP and the Tag Libraries</strong>. Because lots of declarations can be skipped, the web.xml suddenly gets lithe and lissome.</li>
    <li><strong>You don't have to cram all these Tags</strong>. Instead, you deal with the XSLT and XPath standard, knowledge of which you can use outside the Java world.</li>
    <li><strong>You can't put business logic inside your XSL Stylesheets</strong>. Separation of data, application logic, and the graphical representation of data is part of the XSLT concept.</li>
    <li><strong>XSLT is open for all kinds of output formats</strong>: Text, HTML, and XML in all their flavors. There are no HTML-centric concepts like with JSP.</li>
    <li><strong>XSLT guarantees the output of 100 percent well-formed XML</strong>.No more waiting for your JSP to be transformed into servlets and compiled into the Servlet Container. The XSL Stylesheets can be used right out of the box.</li>
    <li>With XSLT, <strong>it's easy to generate an output pipeline for the view</strong> by putting several transformations in a row. This way you can write sequential XSL Stylesheets and send your XML from one to another.</li>
    <li><strong>Separation of layout and style is possible using XSLT</strong>. By defining special layout templates, you can separate the biggest part of your HTML code from the XSL Stylesheets.</li>
    <p><p>As this article has explained, you have plenty of reasons to try StrutsCX. You can begin by <a href="http://sourceforge.net/projects/strutscx" target="_blank">downloading the product</a> and can even take a comprehensive sample application for a test drive (see the <a href="javascript:showSupportItem('sidebar')">Sidebar: The StrutsCX Prototype</a>).</p>
    		</div>
    				</div>
    				<div class="elementor-element elementor-element-4f9883d elementor-widget elementor-widget-post-navigation" data-id="4f9883d" data-element_type="widget" data-widget_type="post-navigation.default">
    				<div class="elementor-widget-container">
    					<div class="elementor-post-navigation">
    			<div class="elementor-post-navigation__prev elementor-post-navigation__link">
    				<a href="https://www.devx.com/get-help/11395/" rel="prev"><span class="elementor-post-navigation__link__prev"><span class="post-navigation__prev--label">Previous</span></span></a>			</div>
    						<div class="elementor-post-navigation__next elementor-post-navigation__link">
    				<a href="https://www.devx.com/tip-bank/18863/" rel="next"><span class="elementor-post-navigation__link__next"><span class="post-navigation__next--label">Next</span></span></a>			</div>
    		</div>
    				</div>
    				</div>
    				<div class="elementor-element elementor-element-2bf5b4bc elementor-widget elementor-widget-heading" data-id="2bf5b4bc" data-element_type="widget" data-widget_type="heading.default">
    				<div class="elementor-widget-container">
    			<span class="elementor-heading-title elementor-size-default">Share the Post:</span>		</div>
    				</div>
    				<div class="elementor-element elementor-element-496b8f65 elementor-share-buttons--view-icon elementor-share-buttons--skin-minimal elementor-share-buttons--color-custom elementor-share-buttons--shape-square elementor-grid-0 elementor-widget elementor-widget-share-buttons" data-id="496b8f65" data-element_type="widget" data-widget_type="share-buttons.default">
    				<div class="elementor-widget-container">
    			<link rel="stylesheet" href="https://www.devx.com/wp-content/plugins/elementor-pro/assets/css/widget-share-buttons.min.css">		<div class="elementor-grid">
    								<div class="elementor-grid-item">
    						<div
    							class="elementor-share-btn elementor-share-btn_facebook"
    							role="button"
    							tabindex="0"
    							aria-label="Share on facebook"
    						>
    															<span class="elementor-share-btn__icon">
    								<i class="fab fa-facebook" aria-hidden="true"></i>							</span>
    																				</div>
    					</div>
    									<div class="elementor-grid-item">
    						<div
    							class="elementor-share-btn elementor-share-btn_twitter"
    							role="button"
    							tabindex="0"
    							aria-label="Share on twitter"
    						>
    															<span class="elementor-share-btn__icon">
    								<i class="fab fa-twitter" aria-hidden="true"></i>							</span>
    																				</div>
    					</div>
    									<div class="elementor-grid-item">
    						<div
    							class="elementor-share-btn elementor-share-btn_linkedin"
    							role="button"
    							tabindex="0"
    							aria-label="Share on linkedin"
    						>
    															<span class="elementor-share-btn__icon">
    								<i class="fab fa-linkedin" aria-hidden="true"></i>							</span>
    																				</div>
    					</div>
    						</div>
    				</div>
    				</div>
    				<div class="elementor-element elementor-element-39bd7056 elementor-grid-1 elementor-posts--thumbnail-right elementor-grid-tablet-2 elementor-grid-mobile-1 load-more-align-center elementor-widget elementor-widget-posts" data-id="39bd7056" data-element_type="widget" data-settings="{"classic_columns":"1","classic_row_gap":{"unit":"px","size":0,"sizes":[]},"pagination_type":"load_more_on_click","classic_columns_tablet":"2","classic_columns_mobile":"1","classic_row_gap_tablet":{"unit":"px","size":"","sizes":[]},"classic_row_gap_mobile":{"unit":"px","size":"","sizes":[]},"load_more_spinner":{"value":"fas fa-spinner","library":"fa-solid"}}" data-widget_type="posts.classic">
    				<div class="elementor-widget-container">
    			<link rel="stylesheet" href="https://www.devx.com/wp-content/plugins/elementor-pro/assets/css/widget-posts.min.css">		<div class="elementor-posts-container elementor-posts elementor-posts--skin-classic elementor-grid">
    				<article class="elementor-post elementor-grid-item post-25986 post type-post status-publish format-standard has-post-thumbnail hentry category-artificial-intelligence-ai category-uncategorized">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/artificial-intelligence-ai/revolutionizing-search-a-glimpse-into-googles-generative-experience/" >
    			<div class="elementor-post__thumbnail"><img width="1920" height="1188" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-26039 ewww_webp" alt="google search" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/google-search.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/google-search.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1188" src="https://www.devx.com/wp-content/uploads/google-search.jpg" class="elementor-animation-grow attachment-full size-full wp-image-26039" alt="google search" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/artificial-intelligence-ai/revolutionizing-search-a-glimpse-into-googles-generative-experience/" >
    				Revolutionizing Search: A Glimpse Into Google’s Generative Experience			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			June 6, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>Google is revolutionizing the search experience as we know it with its latest generative experience. No longer will you be bound by the limitations of traditional keyword searching. Now, you</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-26022 post type-post status-publish format-standard has-post-thumbnail hentry category-office-productivity">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/office-productivity/10-productivity-hacks-to-supercharge-your-business-in-2023/" >
    			<div class="elementor-post__thumbnail"><img width="1920" height="1282" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-26037 ewww_webp" alt="productivity hack" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/productivity-hack.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/productivity-hack.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1282" src="https://www.devx.com/wp-content/uploads/productivity-hack.jpg" class="elementor-animation-grow attachment-full size-full wp-image-26037" alt="productivity hack" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/office-productivity/10-productivity-hacks-to-supercharge-your-business-in-2023/" >
    				10 Productivity Hacks to Supercharge Your Business in 2023			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			June 5, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>Picture this: your team working seamlessly, completing tasks efficiently, and achieving goals with ease. Sounds like too good to be true? Not at all! With our productivity hacks, you can</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-25988 post type-post status-publish format-standard has-post-thumbnail hentry category-devx-daily-news category-uncategorized tag-gm tag-uprotocol">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/uncategorized/gm-creates-open-source-uprotocol-and-invites-automakers-to-adopt-it-revolutionizing-automotive-software-development/" >
    			<div class="elementor-post__thumbnail"><img width="381" height="286" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-26032 ewww_webp" alt="GM Creates Open Source uProtocol and Invites Automakers to Adopt It: Revolutionizing Automotive Software Development." loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/Screenshot-2023-06-02-at-11.30.24-AM.png" data-src-webp="https://www.devx.com/wp-content/uploads/Screenshot-2023-06-02-at-11.30.24-AM.png.webp" data-eio="j" /><noscript><img width="381" height="286" src="https://www.devx.com/wp-content/uploads/Screenshot-2023-06-02-at-11.30.24-AM.png" class="elementor-animation-grow attachment-full size-full wp-image-26032" alt="GM Creates Open Source uProtocol and Invites Automakers to Adopt It: Revolutionizing Automotive Software Development." loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/uncategorized/gm-creates-open-source-uprotocol-and-invites-automakers-to-adopt-it-revolutionizing-automotive-software-development/" >
    				GM Creates Open Source uProtocol and Invites Automakers to Adopt It: Revolutionizing Automotive Software Development.			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			June 2, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>General Motors (GM) recently announced its entry into the Eclipse Foundation. The Eclipse Foundation is a prominent open-source software foundation. In addition, GMC announced its contribution of “uProtocol” to facilitate</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-26024 post type-post status-publish format-standard has-post-thumbnail hentry category-data-access category-data-access-and-management category-devx category-tech-trends tag-ai tag-data-management tag-security tag-technology">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/data-access/what-is-metadata/" >
    			<div class="elementor-post__thumbnail"><img width="1920" height="1280" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-26026 ewww_webp" alt="Heading photo, Metadata." loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/pexels-markus-spiske-2004161.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/pexels-markus-spiske-2004161.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1280" src="https://www.devx.com/wp-content/uploads/pexels-markus-spiske-2004161.jpg" class="elementor-animation-grow attachment-full size-full wp-image-26026" alt="Heading photo, Metadata." loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/data-access/what-is-metadata/" >
    				What is Metadata?			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			June 1, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>What is metadata? Well, It’s an odd concept to wrap your head around. Metadata is essentially the secondary layer of data that tracks details about the “regular” data. The regular</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-26016 post type-post status-publish format-standard has-post-thumbnail hentry category-data-access-and-management">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/data-access-and-management/what-we-should-expect-from-cell-phone-tech-in-the-near-future/" >
    			<div class="elementor-post__thumbnail"><img width="1707" height="2560" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-26017 ewww_webp" alt="cell phones" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/pexels-rdne-stock-project-4921398-scaled.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/pexels-rdne-stock-project-4921398-scaled.jpg.webp" data-eio="j" /><noscript><img width="1707" height="2560" src="https://www.devx.com/wp-content/uploads/pexels-rdne-stock-project-4921398-scaled.jpg" class="elementor-animation-grow attachment-full size-full wp-image-26017" alt="cell phones" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/data-access-and-management/what-we-should-expect-from-cell-phone-tech-in-the-near-future/" >
    				What We Should Expect from Cell Phone Tech in the Near Future			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			May 31, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>The earliest cell phones included boxy designs full of buttons and antennas, and they only made calls. Needless to say, we’ve come a long way from those classic brick phones</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-25678 post type-post status-publish format-standard has-post-thumbnail hentry category-tech-trends category-technology tag-keyboards tag-mechanical-keyboards">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/tech-trends/the-best-mechanical-keyboards-for-programmers-where-to-find-them/" >
    			<div class="elementor-post__thumbnail"><img width="1920" height="1280" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25998 ewww_webp" alt="Where to find the Best Mechanical Keyboards for Programmers" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/pexels-karol-d-841228.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/pexels-karol-d-841228.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1280" src="https://www.devx.com/wp-content/uploads/pexels-karol-d-841228.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25998" alt="Where to find the Best Mechanical Keyboards for Programmers" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/tech-trends/the-best-mechanical-keyboards-for-programmers-where-to-find-them/" >
    				The Best Mechanical Keyboards For Programmers: Where To Find Them			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			May 29, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>When it comes to programming, a good mechanical keyboard can make all the difference. Naturally, you would want one of the best mechanical keyboards for programmers. But with so many</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-26000 post type-post status-publish format-standard has-post-thumbnail hentry category-devx-daily-news tag-big-brother">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/devx-daily-news/the-digital-panopticon-is-big-brother-always-watching-us-online/" >
    			<div class="elementor-post__thumbnail"><img width="1920" height="1280" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-26001 ewww_webp" alt="The Digital Panopticon: Is Big Brother Always Watching Us Online?" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/marvin-meyer-SYTO3xs06fU-unsplash-1.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/marvin-meyer-SYTO3xs06fU-unsplash-1.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1280" src="https://www.devx.com/wp-content/uploads/marvin-meyer-SYTO3xs06fU-unsplash-1.jpg" class="elementor-animation-grow attachment-full size-full wp-image-26001" alt="The Digital Panopticon: Is Big Brother Always Watching Us Online?" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/devx-daily-news/the-digital-panopticon-is-big-brother-always-watching-us-online/" >
    				The Digital Panopticon: Is Big Brother Always Watching Us Online?			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			May 26, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>In the age of digital transformation, the internet has become a ubiquitous part of our lives. From socializing, shopping, and learning to more sensitive activities such as banking and healthcare,</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-25983 post type-post status-publish format-standard has-post-thumbnail hentry category-artificial-intelligence-ai">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/artificial-intelligence-ai/embracing-change-how-ai-is-revolutionizing-the-developers-role/" >
    			<div class="elementor-post__thumbnail"><img width="1920" height="1440" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25984 ewww_webp" alt="web developer" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/web-developer.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/web-developer.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1440" src="https://www.devx.com/wp-content/uploads/web-developer.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25984" alt="web developer" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/artificial-intelligence-ai/embracing-change-how-ai-is-revolutionizing-the-developers-role/" >
    				Embracing Change: How AI Is Revolutionizing the Developer’s Role			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			May 25, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>The world of software development is changing drastically with the introduction of Artificial Intelligence and Machine Learning technologies. In the past, software developers were in charge of the entire development</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-25978 post type-post status-publish format-standard has-post-thumbnail hentry category-security">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/security/the-benefits-of-using-xdr-solutions/" >
    			<div class="elementor-post__thumbnail"><img width="512" height="342" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25979 ewww_webp" alt="XDR solutions" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/XDR-solutions.jpeg" data-src-webp="https://www.devx.com/wp-content/uploads/XDR-solutions.jpeg.webp" data-eio="j" /><noscript><img width="512" height="342" src="https://www.devx.com/wp-content/uploads/XDR-solutions.jpeg" class="elementor-animation-grow attachment-full size-full wp-image-25979" alt="XDR solutions" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/security/the-benefits-of-using-xdr-solutions/" >
    				The Benefits of Using XDR Solutions			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			May 24, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>Cybercriminals constantly adapt their strategies, developing newer, more powerful, and intelligent ways to attack your network. Since security professionals must innovate as well, more conventional endpoint detection solutions have evolved</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-25973 post type-post status-publish format-standard has-post-thumbnail hentry category-artificial-intelligence-ai category-security">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/artificial-intelligence-ai/how-ai-is-revolutionizing-fraud-detection/" >
    			<div class="elementor-post__thumbnail"><img width="512" height="341" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25975 ewww_webp" alt="AI is revolutionizing fraud detection" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/AI-is-revolutionizing-fraud-detection.jpeg" data-src-webp="https://www.devx.com/wp-content/uploads/AI-is-revolutionizing-fraud-detection.jpeg.webp" data-eio="j" /><noscript><img width="512" height="341" src="https://www.devx.com/wp-content/uploads/AI-is-revolutionizing-fraud-detection.jpeg" class="elementor-animation-grow attachment-full size-full wp-image-25975" alt="AI is revolutionizing fraud detection" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/artificial-intelligence-ai/how-ai-is-revolutionizing-fraud-detection/" >
    				How AI is Revolutionizing Fraud Detection			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			May 23, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>Artificial intelligence – commonly known as AI – means a form of technology with multiple uses. As a result, it has become extremely valuable to a number of businesses across</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-25410 post type-post status-publish format-standard has-post-thumbnail hentry category-artificial-intelligence-ai">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/artificial-intelligence-ai/companies-leading-ai-innovation-in-2023/" >
    			<div class="elementor-post__thumbnail"><img width="1920" height="1440" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25968 ewww_webp" alt="AI innovation" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/AI-innovation.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/AI-innovation.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1440" src="https://www.devx.com/wp-content/uploads/AI-innovation.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25968" alt="AI innovation" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/artificial-intelligence-ai/companies-leading-ai-innovation-in-2023/" >
    				Companies Leading AI Innovation in 2023			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			May 22, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>Artificial intelligence (AI) has been transforming industries and revolutionizing business operations. AI’s potential to enhance efficiency and productivity has become crucial to many businesses. As we move into 2023, several</p>
    		</div>
    				</div>
    				</article>
    				<article class="elementor-post elementor-grid-item post-25406 post type-post status-publish format-standard has-post-thumbnail hentry category-enterprise category-uncategorized category-small-business category-tools">
    				<a class="elementor-post__thumbnail__link" href="https://www.devx.com/small-business/step-by-step-guide-to-properly-copyright-your-website/" >
    			<div class="elementor-post__thumbnail"><img width="1920" height="1277" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25961 ewww_webp" alt="copyright your website" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/copyright-your-website.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/copyright-your-website.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1277" src="https://www.devx.com/wp-content/uploads/copyright-your-website.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25961" alt="copyright your website" loading="lazy" /></noscript></div>
    		</a>
    				<div class="elementor-post__text">
    				<h3 class="elementor-post__title">
    			<a href="https://www.devx.com/small-business/step-by-step-guide-to-properly-copyright-your-website/" >
    				Step-by-Step Guide to Properly Copyright Your Website			</a>
    		</h3>
    				<div class="elementor-post__meta-data">
    					<span class="elementor-post-date">
    			May 18, 2023		</span>
    				</div>
    				<div class="elementor-post__excerpt">
    			<p>Creating a website is not easy, but protecting your website is equally important. Implementing copyright laws ensures that the substance of your website remains secure and sheltered. Copyrighting your website</p>
    		</div>
    				</div>
    				</article>
    				</div>
    					<span class="e-load-more-spinner">
    				<i aria-hidden="true" class="fas fa-spinner"></i>			</span>
    		
    				<div class="e-load-more-anchor" data-page="1" data-max-page="1499" data-next-page="https://www.devx.com/java-zone/11381/2/"></div>
    				<div class="elementor-button-wrapper">
    			<a href="#" class="elementor-button-link elementor-button elementor-animation-grow" role="button">
    						<span class="elementor-button-content-wrapper">
    						<span class="elementor-button-text">Show More</span>
    		</span>
    					</a>
    		</div>
    				<div class="e-load-more-message"></div>
    				</div>
    				</div>
    					</div>
    		</div>
    							</div>
    		</section>
    					</div>
    		</div>
    				<div class="elementor-column elementor-col-20 elementor-top-column elementor-element elementor-element-270dc71" data-id="270dc71" data-element_type="column">
    			<div class="elementor-widget-wrap">
    									</div>
    		</div>
    				<div class="elementor-column elementor-col-20 elementor-top-column elementor-element elementor-element-8905b95 elementor-hidden-tablet" data-id="8905b95" data-element_type="column">
    			<div class="elementor-widget-wrap elementor-element-populated">
    								<div class="elementor-element elementor-element-46d69df elementor-widget elementor-widget-html" data-id="46d69df" data-element_type="widget" data-widget_type="html.default">
    				<div class="elementor-widget-container">
    			
        <iframe
          id="JotFormIFrame-230167013128041"
          title="Daily Technology News Straight to Your Inbox"
          onload="window.parent.scrollTo(0,0)"
          allowtransparency="true"
          allowfullscreen="true"
          allow="geolocation; microphone; camera"
          src="https://form.jotform.com/230167013128041"
          frameborder="0"
          style="
          min-width: 100%;
          height:539px;
          border:none;"
          scrolling="no"
        >
        </iframe>
        <script type="text/javascript">
        var ifr = document.getElementById("JotFormIFrame-230167013128041");
        if (ifr) {
          var src = ifr.src;
          var iframeParams = [];
          if (window.location.href && window.location.href.indexOf("?") > -1) {
            iframeParams = iframeParams.concat(window.location.href.substr(window.location.href.indexOf("?") + 1).split('&'));
          }
          if (src && src.indexOf("?") > -1) {
            iframeParams = iframeParams.concat(src.substr(src.indexOf("?") + 1).split("&"));
            src = src.substr(0, src.indexOf("?"))
          }
          iframeParams.push("isIframeEmbed=1");
          ifr.src = src + "?" + iframeParams.join('&');
        }
        window.handleIFrameMessage = function(e) {
          if (typeof e.data === 'object') { return; }
          var args = e.data.split(":");
          if (args.length > 2) { iframe = document.getElementById("JotFormIFrame-" + args[(args.length - 1)]); } else { iframe = document.getElementById("JotFormIFrame"); }
          if (!iframe) { return; }
          switch (args[0]) {
            case "scrollIntoView":
              iframe.scrollIntoView();
              break;
            case "setHeight":
              iframe.style.height = args[1] + "px";
              if (!isNaN(args[1]) && parseInt(iframe.style.minHeight) > parseInt(args[1])) {
                iframe.style.minHeight = args[1] + "px";
              }
              break;
            case "collapseErrorPage":
              if (iframe.clientHeight > window.innerHeight) {
                iframe.style.height = window.innerHeight + "px";
              }
              break;
            case "reloadPage":
              window.location.reload();
              break;
            case "loadScript":
              if( !window.isPermitted(e.origin, ['jotform.com', 'jotform.pro']) ) { break; }
              var src = args[1];
              if (args.length > 3) {
                  src = args[1] + ':' + args[2];
              }
              var script = document.createElement('script');
              script.src = src;
              script.type = 'text/javascript';
              document.body.appendChild(script);
              break;
            case "exitFullscreen":
              if      (window.document.exitFullscreen)        window.document.exitFullscreen();
              else if (window.document.mozCancelFullScreen)   window.document.mozCancelFullScreen();
              else if (window.document.mozCancelFullscreen)   window.document.mozCancelFullScreen();
              else if (window.document.webkitExitFullscreen)  window.document.webkitExitFullscreen();
              else if (window.document.msExitFullscreen)      window.document.msExitFullscreen();
              break;
          }
          var isJotForm = (e.origin.indexOf("jotform") > -1) ? true : false;
          if(isJotForm && "contentWindow" in iframe && "postMessage" in iframe.contentWindow) {
            var urls = {"docurl":encodeURIComponent(document.URL),"referrer":encodeURIComponent(document.referrer)};
            iframe.contentWindow.postMessage(JSON.stringify({"type":"urls","value":urls}), "*");
          }
        };
        window.isPermitted = function(originUrl, whitelisted_domains) {
          var url = document.createElement('a');
          url.href = originUrl;
          var hostname = url.hostname;
          var result = false;
          if( typeof hostname !== 'undefined' ) {
            whitelisted_domains.forEach(function(element) {
                if( hostname.slice((-1 * element.length - 1)) === '.'.concat(element) ||  hostname === element ) {
                    result = true;
                }
            });
            return result;
          }
        };
        if (window.addEventListener) {
          window.addEventListener("message", handleIFrameMessage, false);
        } else if (window.attachEvent) {
          window.attachEvent("onmessage", handleIFrameMessage);
        }
        </script>
    
    		</div>
    				</div>
    				<div class="elementor-element elementor-element-7c9513d elementor-widget elementor-widget-html" data-id="7c9513d" data-element_type="widget" data-settings="{"sticky_offset":10,"sticky_parent":"yes","sticky":"top","sticky_on":["desktop","tablet","mobile"],"sticky_effects_offset":0}" data-widget_type="html.default">
    				<div class="elementor-widget-container">
    			<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1183579825777021"
         crossorigin="anonymous"></script>
    <!-- devx top -->
    <ins class="adsbygoogle"
         style="display:inline-block;width:300px;height:600px"
         data-ad-client="ca-pub-1183579825777021"
         data-ad-slot="2250810506"></ins>
    <script>
         (adsbygoogle = window.adsbygoogle || []).push({});
    </script>		</div>
    				</div>
    					</div>
    		</div>
    							</div>
    		</section>
    				<section class="elementor-section elementor-top-section elementor-element elementor-element-7ef94119 elementor-hidden-mobile elementor-hidden-tablet elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="7ef94119" data-element_type="section">
    						<div class="elementor-container elementor-column-gap-default">
    					<div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-cb0d3b5" data-id="cb0d3b5" data-element_type="column">
    			<div class="elementor-widget-wrap">
    									</div>
    		</div>
    				<div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-dcd3813" data-id="dcd3813" data-element_type="column">
    			<div class="elementor-widget-wrap">
    									</div>
    		</div>
    							</div>
    		</section>
    						</div>
    				<footer data-elementor-type="footer" data-elementor-id="23300" class="elementor elementor-23300 elementor-location-footer">
    								<footer class="elementor-section elementor-top-section elementor-element elementor-element-1588a538 elementor-section-height-min-height elementor-section-content-middle elementor-section-full_width elementor-section-height-default elementor-section-items-middle" data-id="1588a538" data-element_type="section" data-settings="{"background_background":"classic"}">
    						<div class="elementor-container elementor-column-gap-no">
    					<div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-9d2a788" data-id="9d2a788" data-element_type="column">
    			<div class="elementor-widget-wrap">
    									</div>
    		</div>
    				<div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-2e0ce949" data-id="2e0ce949" data-element_type="column">
    			<div class="elementor-widget-wrap elementor-element-populated">
    								<div class="elementor-element elementor-element-4f9ec08 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="4f9ec08" data-element_type="widget" data-widget_type="divider.default">
    				<div class="elementor-widget-container">
    			<style>/*! elementor - v3.12.2 - 23-04-2023 */
    .elementor-widget-divider{--divider-border-style:none;--divider-border-width:1px;--divider-color:#0c0d0e;--divider-icon-size:20px;--divider-element-spacing:10px;--divider-pattern-height:24px;--divider-pattern-size:20px;--divider-pattern-url:none;--divider-pattern-repeat:repeat-x}.elementor-widget-divider .elementor-divider{display:flex}.elementor-widget-divider .elementor-divider__text{font-size:15px;line-height:1;max-width:95%}.elementor-widget-divider .elementor-divider__element{margin:0 var(--divider-element-spacing);flex-shrink:0}.elementor-widget-divider .elementor-icon{font-size:var(--divider-icon-size)}.elementor-widget-divider .elementor-divider-separator{display:flex;margin:0;direction:ltr}.elementor-widget-divider--view-line_icon .elementor-divider-separator,.elementor-widget-divider--view-line_text .elementor-divider-separator{align-items:center}.elementor-widget-divider--view-line_icon .elementor-divider-separator:after,.elementor-widget-divider--view-line_icon .elementor-divider-separator:before,.elementor-widget-divider--view-line_text .elementor-divider-separator:after,.elementor-widget-divider--view-line_text .elementor-divider-separator:before{display:block;content:"";border-bottom:0;flex-grow:1;border-top:var(--divider-border-width) var(--divider-border-style) var(--divider-color)}.elementor-widget-divider--element-align-left .elementor-divider .elementor-divider-separator>.elementor-divider__svg:first-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-left .elementor-divider-separator:before{content:none}.elementor-widget-divider--element-align-left .elementor-divider__element{margin-left:0}.elementor-widget-divider--element-align-right .elementor-divider .elementor-divider-separator>.elementor-divider__svg:last-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-right .elementor-divider-separator:after{content:none}.elementor-widget-divider--element-align-right .elementor-divider__element{margin-right:0}.elementor-widget-divider:not(.elementor-widget-divider--view-line_text):not(.elementor-widget-divider--view-line_icon) .elementor-divider-separator{border-top:var(--divider-border-width) var(--divider-border-style) var(--divider-color)}.elementor-widget-divider--separator-type-pattern{--divider-border-style:none}.elementor-widget-divider--separator-type-pattern.elementor-widget-divider--view-line .elementor-divider-separator,.elementor-widget-divider--separator-type-pattern:not(.elementor-widget-divider--view-line) .elementor-divider-separator:after,.elementor-widget-divider--separator-type-pattern:not(.elementor-widget-divider--view-line) .elementor-divider-separator:before,.elementor-widget-divider--separator-type-pattern:not([class*=elementor-widget-divider--view]) .elementor-divider-separator{width:100%;min-height:var(--divider-pattern-height);-webkit-mask-size:var(--divider-pattern-size) 100%;mask-size:var(--divider-pattern-size) 100%;-webkit-mask-repeat:var(--divider-pattern-repeat);mask-repeat:var(--divider-pattern-repeat);background-color:var(--divider-color);-webkit-mask-image:var(--divider-pattern-url);mask-image:var(--divider-pattern-url)}.elementor-widget-divider--no-spacing{--divider-pattern-size:auto}.elementor-widget-divider--bg-round{--divider-pattern-repeat:round}.rtl .elementor-widget-divider .elementor-divider__text{direction:rtl}.e-con-inner>.elementor-widget-divider,.e-con>.elementor-widget-divider{width:var(--container-widget-width,100%);--flex-grow:var(--container-widget-flex-grow)}</style>		<div class="elementor-divider">
    			<span class="elementor-divider-separator">
    						</span>
    		</div>
    				</div>
    				</div>
    				<section class="elementor-section elementor-inner-section elementor-element elementor-element-73a9986 elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="73a9986" data-element_type="section">
    						<div class="elementor-container elementor-column-gap-default">
    					<div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-7f08930" data-id="7f08930" data-element_type="column">
    			<div class="elementor-widget-wrap elementor-element-populated">
    								<div class="elementor-element elementor-element-269b367 elementor-nav-menu__align-center elementor-nav-menu--dropdown-tablet elementor-nav-menu__text-align-aside elementor-nav-menu--toggle elementor-nav-menu--burger elementor-widget elementor-widget-nav-menu" data-id="269b367" data-element_type="widget" data-settings="{"layout":"horizontal","submenu_icon":{"value":"<i class=\"fas fa-caret-down\"><\/i>","library":"fa-solid"},"toggle":"burger"}" data-widget_type="nav-menu.default">
    				<div class="elementor-widget-container">
    						<nav class="elementor-nav-menu--main elementor-nav-menu__container elementor-nav-menu--layout-horizontal e--pointer-underline e--animation-fade">
    				<ul id="menu-1-269b367" class="elementor-nav-menu"><li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-home menu-item-23808"><a href="https://www.devx.com/" class="elementor-item">Home</a></li>
    <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23809"><a href="https://www.devx.com/advertise/" class="elementor-item">Advertise</a></li>
    <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23816"><a href="https://www.devx.com/about/" class="elementor-item">About</a></li>
    </ul>			</nav>
    					<div class="elementor-menu-toggle" role="button" tabindex="0" aria-label="Menu Toggle" aria-expanded="false">
    			<i aria-hidden="true" role="presentation" class="elementor-menu-toggle__icon--open eicon-menu-bar"></i><i aria-hidden="true" role="presentation" class="elementor-menu-toggle__icon--close eicon-close"></i>			<span class="elementor-screen-only">Menu</span>
    		</div>
    					<nav class="elementor-nav-menu--dropdown elementor-nav-menu__container" aria-hidden="true">
    				<ul id="menu-2-269b367" class="elementor-nav-menu"><li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-home menu-item-23808"><a href="https://www.devx.com/" class="elementor-item" tabindex="-1">Home</a></li>
    <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23809"><a href="https://www.devx.com/advertise/" class="elementor-item" tabindex="-1">Advertise</a></li>
    <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23816"><a href="https://www.devx.com/about/" class="elementor-item" tabindex="-1">About</a></li>
    </ul>			</nav>
    				</div>
    				</div>
    					</div>
    		</div>
    				<div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-21928d3" data-id="21928d3" data-element_type="column">
    			<div class="elementor-widget-wrap">
    									</div>
    		</div>
    				<div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-869862d" data-id="869862d" data-element_type="column">
    			<div class="elementor-widget-wrap elementor-element-populated">
    								<div class="elementor-element elementor-element-5d5f4dc5 e-grid-align-left elementor-shape-rounded elementor-grid-0 elementor-widget elementor-widget-social-icons" data-id="5d5f4dc5" data-element_type="widget" data-widget_type="social-icons.default">
    				<div class="elementor-widget-container">
    			<style>/*! elementor - v3.12.2 - 23-04-2023 */
    .elementor-widget-social-icons.elementor-grid-0 .elementor-widget-container,.elementor-widget-social-icons.elementor-grid-mobile-0 .elementor-widget-container,.elementor-widget-social-icons.elementor-grid-tablet-0 .elementor-widget-container{line-height:1;font-size:0}.elementor-widget-social-icons:not(.elementor-grid-0):not(.elementor-grid-tablet-0):not(.elementor-grid-mobile-0) .elementor-grid{display:inline-grid}.elementor-widget-social-icons .elementor-grid{grid-column-gap:var(--grid-column-gap,5px);grid-row-gap:var(--grid-row-gap,5px);grid-template-columns:var(--grid-template-columns);justify-content:var(--justify-content,center);justify-items:var(--justify-content,center)}.elementor-icon.elementor-social-icon{font-size:var(--icon-size,25px);line-height:var(--icon-size,25px);width:calc(var(--icon-size, 25px) + (2 * var(--icon-padding, .5em)));height:calc(var(--icon-size, 25px) + (2 * var(--icon-padding, .5em)))}.elementor-social-icon{--e-social-icon-icon-color:#fff;display:inline-flex;background-color:#69727d;align-items:center;justify-content:center;text-align:center;cursor:pointer}.elementor-social-icon i{color:var(--e-social-icon-icon-color)}.elementor-social-icon svg{fill:var(--e-social-icon-icon-color)}.elementor-social-icon:last-child{margin:0}.elementor-social-icon:hover{opacity:.9;color:#fff}.elementor-social-icon-android{background-color:#a4c639}.elementor-social-icon-apple{background-color:#999}.elementor-social-icon-behance{background-color:#1769ff}.elementor-social-icon-bitbucket{background-color:#205081}.elementor-social-icon-codepen{background-color:#000}.elementor-social-icon-delicious{background-color:#39f}.elementor-social-icon-deviantart{background-color:#05cc47}.elementor-social-icon-digg{background-color:#005be2}.elementor-social-icon-dribbble{background-color:#ea4c89}.elementor-social-icon-elementor{background-color:#d30c5c}.elementor-social-icon-envelope{background-color:#ea4335}.elementor-social-icon-facebook,.elementor-social-icon-facebook-f{background-color:#3b5998}.elementor-social-icon-flickr{background-color:#0063dc}.elementor-social-icon-foursquare{background-color:#2d5be3}.elementor-social-icon-free-code-camp,.elementor-social-icon-freecodecamp{background-color:#006400}.elementor-social-icon-github{background-color:#333}.elementor-social-icon-gitlab{background-color:#e24329}.elementor-social-icon-globe{background-color:#69727d}.elementor-social-icon-google-plus,.elementor-social-icon-google-plus-g{background-color:#dd4b39}.elementor-social-icon-houzz{background-color:#7ac142}.elementor-social-icon-instagram{background-color:#262626}.elementor-social-icon-jsfiddle{background-color:#487aa2}.elementor-social-icon-link{background-color:#818a91}.elementor-social-icon-linkedin,.elementor-social-icon-linkedin-in{background-color:#0077b5}.elementor-social-icon-medium{background-color:#00ab6b}.elementor-social-icon-meetup{background-color:#ec1c40}.elementor-social-icon-mixcloud{background-color:#273a4b}.elementor-social-icon-odnoklassniki{background-color:#f4731c}.elementor-social-icon-pinterest{background-color:#bd081c}.elementor-social-icon-product-hunt{background-color:#da552f}.elementor-social-icon-reddit{background-color:#ff4500}.elementor-social-icon-rss{background-color:#f26522}.elementor-social-icon-shopping-cart{background-color:#4caf50}.elementor-social-icon-skype{background-color:#00aff0}.elementor-social-icon-slideshare{background-color:#0077b5}.elementor-social-icon-snapchat{background-color:#fffc00}.elementor-social-icon-soundcloud{background-color:#f80}.elementor-social-icon-spotify{background-color:#2ebd59}.elementor-social-icon-stack-overflow{background-color:#fe7a15}.elementor-social-icon-steam{background-color:#00adee}.elementor-social-icon-stumbleupon{background-color:#eb4924}.elementor-social-icon-telegram{background-color:#2ca5e0}.elementor-social-icon-thumb-tack{background-color:#1aa1d8}.elementor-social-icon-tripadvisor{background-color:#589442}.elementor-social-icon-tumblr{background-color:#35465c}.elementor-social-icon-twitch{background-color:#6441a5}.elementor-social-icon-twitter{background-color:#1da1f2}.elementor-social-icon-viber{background-color:#665cac}.elementor-social-icon-vimeo{background-color:#1ab7ea}.elementor-social-icon-vk{background-color:#45668e}.elementor-social-icon-weibo{background-color:#dd2430}.elementor-social-icon-weixin{background-color:#31a918}.elementor-social-icon-whatsapp{background-color:#25d366}.elementor-social-icon-wordpress{background-color:#21759b}.elementor-social-icon-xing{background-color:#026466}.elementor-social-icon-yelp{background-color:#af0606}.elementor-social-icon-youtube{background-color:#cd201f}.elementor-social-icon-500px{background-color:#0099e5}.elementor-shape-rounded .elementor-icon.elementor-social-icon{border-radius:10%}.elementor-shape-circle .elementor-icon.elementor-social-icon{border-radius:50%}</style>		<div class="elementor-social-icons-wrapper elementor-grid">
    							<span class="elementor-grid-item">
    					<a class="elementor-icon elementor-social-icon elementor-social-icon-linkedin elementor-repeater-item-5c0ce3c" href="https://www.linkedin.com/company/devx" target="_blank">
    						<span class="elementor-screen-only">Linkedin</span>
    						<i class="fab fa-linkedin"></i>					</a>
    				</span>
    							<span class="elementor-grid-item">
    					<a class="elementor-icon elementor-social-icon elementor-social-icon-twitter elementor-repeater-item-828f132" href="https://twitter.com/DevX_Com" target="_blank">
    						<span class="elementor-screen-only">Twitter</span>
    						<i class="fab fa-twitter"></i>					</a>
    				</span>
    					</div>
    				</div>
    				</div>
    					</div>
    		</div>
    							</div>
    		</section>
    				<div class="elementor-element elementor-element-6963de5 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="6963de5" data-element_type="widget" data-widget_type="divider.default">
    				<div class="elementor-widget-container">
    					<div class="elementor-divider">
    			<span class="elementor-divider-separator">
    						</span>
    		</div>
    				</div>
    				</div>
    					</div>
    		</div>
    							</div>
    		</footer>
    				<section class="elementor-section elementor-top-section elementor-element elementor-element-a4f01a6 elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="a4f01a6" data-element_type="section">
    						<div class="elementor-container elementor-column-gap-default">
    					<div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-a1bc5b1" data-id="a1bc5b1" data-element_type="column">
    			<div class="elementor-widget-wrap">
    									</div>
    		</div>
    				<div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-e4f110b" data-id="e4f110b" data-element_type="column">
    			<div class="elementor-widget-wrap elementor-element-populated">
    								<div class="elementor-element elementor-element-4a914653 elementor-widget elementor-widget-heading" data-id="4a914653" data-element_type="widget" data-widget_type="heading.default">
    				<div class="elementor-widget-container">
    			<p class="elementor-heading-title elementor-size-default">©2023 Copyright DevX - All Rights Reserved. Registration or use of this site constitutes acceptance of our Terms of Service and Privacy Policy.</p>		</div>
    				</div>
    				<div class="elementor-element elementor-element-d2cf216 elementor-widget elementor-widget-text-editor" data-id="d2cf216" data-element_type="widget" data-widget_type="text-editor.default">
    				<div class="elementor-widget-container">
    			<style>/*! elementor - v3.12.2 - 23-04-2023 */
    .elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:#69727d;color:#fff}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap{color:#69727d;border:3px solid;background-color:transparent}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap{margin-top:8px}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap-letter{width:1em;height:1em}.elementor-widget-text-editor .elementor-drop-cap{float:left;text-align:center;line-height:1;font-size:50px}.elementor-widget-text-editor .elementor-drop-cap-letter{display:inline-block}</style>				<p><strong><a href="https://www.devx.com/sitemap/">Sitemap</a></strong></p>						</div>
    				</div>
    					</div>
    		</div>
    							</div>
    		</section>
    						</footer>
    		
    <link rel='stylesheet' id='elementor-icons-fa-regular-css' href='https://www.devx.com/wp-content/plugins/elementor/assets/lib/font-awesome/css/regular.min.css?ver=5.15.3' type='text/css' media='all' />
    <link rel='stylesheet' id='e-animations-css' href='https://www.devx.com/wp-content/plugins/elementor/assets/lib/animations/animations.min.css?ver=3.12.2' type='text/css' media='all' />
    <script type='text/javascript' src='https://www.devx.com/wp-content/themes/devxnew/assets/js/hello-frontend.min.js?ver=1.0.0' id='hello-theme-frontend-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/lib/smartmenus/jquery.smartmenus.min.js?ver=1.0.1' id='smartmenus-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-includes/js/imagesloaded.min.js?ver=4.1.4' id='imagesloaded-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/js/webpack-pro.runtime.min.js?ver=3.12.3' id='elementor-pro-webpack-runtime-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor/assets/js/webpack.runtime.min.js?ver=3.12.2' id='elementor-webpack-runtime-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor/assets/js/frontend-modules.min.js?ver=3.12.2' id='elementor-frontend-modules-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/vendor/wp-polyfill-inert.min.js?ver=3.1.2' id='wp-polyfill-inert-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/vendor/regenerator-runtime.min.js?ver=0.13.11' id='regenerator-runtime-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/vendor/wp-polyfill.min.js?ver=3.15.0' id='wp-polyfill-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/hooks.min.js?ver=4169d3cf8e8d95a3d6d5' id='wp-hooks-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/i18n.min.js?ver=9e794f35a71bb98672ae' id='wp-i18n-js'></script>
    <script type='text/javascript' id='wp-i18n-js-after'>
    wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );
    </script>
    <script type='text/javascript' id='elementor-pro-frontend-js-before'>
    var ElementorProFrontendConfig = {"ajaxurl":"https:\/\/www.devx.com\/wp-admin\/admin-ajax.php","nonce":"aadd40f889","urls":{"assets":"https:\/\/www.devx.com\/wp-content\/plugins\/elementor-pro\/assets\/","rest":"https:\/\/www.devx.com\/wp-json\/"},"shareButtonsNetworks":{"facebook":{"title":"Facebook","has_counter":true},"twitter":{"title":"Twitter"},"linkedin":{"title":"LinkedIn","has_counter":true},"pinterest":{"title":"Pinterest","has_counter":true},"reddit":{"title":"Reddit","has_counter":true},"vk":{"title":"VK","has_counter":true},"odnoklassniki":{"title":"OK","has_counter":true},"tumblr":{"title":"Tumblr"},"digg":{"title":"Digg"},"skype":{"title":"Skype"},"stumbleupon":{"title":"StumbleUpon","has_counter":true},"mix":{"title":"Mix"},"telegram":{"title":"Telegram"},"pocket":{"title":"Pocket","has_counter":true},"xing":{"title":"XING","has_counter":true},"whatsapp":{"title":"WhatsApp"},"email":{"title":"Email"},"print":{"title":"Print"}},"facebook_sdk":{"lang":"en_US","app_id":""},"lottie":{"defaultAnimationUrl":"https:\/\/www.devx.com\/wp-content\/plugins\/elementor-pro\/modules\/lottie\/assets\/animations\/default.json"}};
    </script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/js/frontend.min.js?ver=3.12.3' id='elementor-pro-frontend-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor/assets/lib/waypoints/waypoints.min.js?ver=4.0.2' id='elementor-waypoints-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-includes/js/jquery/ui/core.min.js?ver=1.13.2' id='jquery-ui-core-js'></script>
    <script type='text/javascript' id='elementor-frontend-js-before'>
    var elementorFrontendConfig = {"environmentMode":{"edit":false,"wpPreview":false,"isScriptDebug":false},"i18n":{"shareOnFacebook":"Share on Facebook","shareOnTwitter":"Share on Twitter","pinIt":"Pin it","download":"Download","downloadImage":"Download image","fullscreen":"Fullscreen","zoom":"Zoom","share":"Share","playVideo":"Play Video","previous":"Previous","next":"Next","close":"Close"},"is_rtl":false,"breakpoints":{"xs":0,"sm":480,"md":768,"lg":1025,"xl":1440,"xxl":1600},"responsive":{"breakpoints":{"mobile":{"label":"Mobile Portrait","value":767,"default_value":767,"direction":"max","is_enabled":true},"mobile_extra":{"label":"Mobile Landscape","value":880,"default_value":880,"direction":"max","is_enabled":false},"tablet":{"label":"Tablet Portrait","value":1024,"default_value":1024,"direction":"max","is_enabled":true},"tablet_extra":{"label":"Tablet Landscape","value":1200,"default_value":1200,"direction":"max","is_enabled":false},"laptop":{"label":"Laptop","value":1366,"default_value":1366,"direction":"max","is_enabled":false},"widescreen":{"label":"Widescreen","value":2400,"default_value":2400,"direction":"min","is_enabled":false}}},"version":"3.12.2","is_static":false,"experimentalFeatures":{"e_dom_optimization":true,"e_optimized_assets_loading":true,"e_optimized_css_loading":true,"a11y_improvements":true,"additional_custom_breakpoints":true,"theme_builder_v2":true,"hello-theme-header-footer":true,"landing-pages":true,"page-transitions":true,"notes":true,"loop":true,"form-submissions":true,"e_scroll_snap":true},"urls":{"assets":"https:\/\/www.devx.com\/wp-content\/plugins\/elementor\/assets\/"},"swiperClass":"swiper-container","settings":{"page":[],"editorPreferences":[]},"kit":{"body_background_background":"classic","active_breakpoints":["viewport_mobile","viewport_tablet"],"global_image_lightbox":"yes","lightbox_enable_counter":"yes","lightbox_enable_fullscreen":"yes","lightbox_enable_zoom":"yes","lightbox_enable_share":"yes","lightbox_title_src":"title","lightbox_description_src":"description","hello_header_logo_type":"logo","hello_header_menu_layout":"horizontal","hello_footer_logo_type":"logo"},"post":{"id":11402,"title":"Generate%20Web%20Output%20in%20Multiple%20Formats%20and%20Languages%20with%20StrutsCX%20-%20DevX","excerpt":"","featuredImage":"https:\/\/www.devx.com\/wp-content\/uploads\/2022\/02\/thumbnail.jpg"}};
    </script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor/assets/js/frontend.min.js?ver=3.12.2' id='elementor-frontend-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/js/elements-handlers.min.js?ver=3.12.3' id='pro-elements-handlers-js'></script>
    <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/lib/sticky/jquery.sticky.min.js?ver=3.12.3' id='e-sticky-js'></script>
    
    </body>
    </html>
    
    <!-- Dynamic page generated in 1.144 seconds. -->
    <!-- Cached page generated by WP-Super-Cache on 2023-06-07 13:29:21 -->
    
    <!-- Compression = gzip -->