Carlos Cifuentes
Modernization · Java and JSP

Migrating AngularJS that lives inside Java and JSP

In many Java systems, AngularJS is delivered by JSP pages and packaged in the same WAR as the backend. Migrating it means separating three things first: the pages, the build and the session.

By Carlos Cifuentes · Frontend architect · Updated 2026-10-02

The starting point

A common setup looks like this. Spring MVC controllers return JSP views. A layout built with Tiles, SiteMesh or JSP includes renders the header and the script tags. AngularJS files sit in the web application folder, sometimes minified by a Maven plugin and sometimes included one by one. Everything is packaged into a single WAR and deployed to an application server on the backend's release schedule.

The frontend therefore depends on the server in three layers. Each one needs its own work.

Layer 1: The pages

JSP mixes server logic into the markup that AngularJS later uses:

  • Tags that show or hide parts of the page according to the user's roles.
  • Message tags that insert translated text from resource bundles.
  • Model attributes written into inline scripts as JavaScript variables.
  • The CSRF token rendered into a meta tag or a hidden field.

Modern Angular compiles static templates at build time, so none of this can stay in the templates.

What to do

  1. Search the JSP files for server tags and expressions, and list each use.
  2. Expose the current user and permissions through a REST endpoint. The server continues to enforce access on every request.
  3. Publish the message bundles as JSON, per language, so the client can load its translations.
  4. Replace inline model data with calls to REST controllers.
  5. Reduce each JSP to a thin page that only loads the application. Finally, replace it with a static index.html.

Layer 2: The build

The Angular toolchain runs on Node. The backend builds with Maven or Gradle. They have to meet somewhere.

OptionHow it worksTrade-off
Frontend build inside Maven or GradleA plugin installs Node and runs the Angular build during the backend build. The output is copied into the WAR or JAROne artifact and one pipeline. Builds are slower, and frontend and backend releases stay tied
Separate pipeline, same artifactCI builds the frontend first and passes the static files to the backend buildFaster feedback for each side. Still one deployable unit
Separate deploymentStatic files are served by a web server or CDN. A reverse proxy sends API paths to the Java applicationIndependent releases. Needs proxy configuration and API compatibility between versions

Starting with the first or second option keeps operations unchanged during the migration. Moving to the third later is straightforward once the frontend is a set of static files.

Two details save time:

  • Context path. If the application is deployed under a path such as /portal, set the same base path in the Angular build. Otherwise scripts and routes break only in the deployed environment.
  • Local development. Run the Angular development server with a proxy to the local backend. Requests then look same-origin, and session cookies work as in production.

Layer 3: The session

Java web applications usually keep a server-side session identified by a JSESSIONID cookie. A SPA served from the same origin sends this cookie with every request, so the login can stay as it is. The work is in the edges.

  • Session timeout. When the session expires, the security layer redirects to the login page. An API call then receives HTML with a 200 status. Configure API paths to answer with 401, and let one HTTP interceptor in the client send the user to the login.
  • CSRF. Replace the token rendered by JSP with the cookie-and-header approach. Spring Security can publish the token in a cookie that Angular's HTTP client reads and returns in a header. Check the documentation for your Spring Security version, because the configuration differs between major versions.
  • State kept in the session. Look for wizard steps, selected records or filters stored in the HTTP session. The old pages relied on them between requests. Decide for each one whether it moves to the client, becomes an explicit API parameter or stays on the server behind an endpoint.

Session state stored on the server is a hidden coupling that causes many surprises. A screen may work only because a previous screen placed something in the session. Trace these dependencies before estimating the screens involved.

After the separation

Once the three layers are separated, screens move one at a time, as described in How to migrate AngularJS to Angular without downtime. The frontend ends up as static files that talk to an API, so the Java side can be upgraded without touching the screens.

The same structure applies to .NET systems, described in AngularJS with ASP.NET MVC. For the concept mapping between the two frameworks, see the AngularJS to Angular reference.

More in this section

Planning a migration or a micro-frontend platform?

In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.

Message me on LinkedIn