Create a Panchang Viewer Web App Using Java Servlets & MySQL



Servlet Collaboration for Multi-Module IKS Applications

Building large Indian Knowledge Systems (IKS) web apps often means multiple servlets and modules must work together — for example, linking Panchatantra stories to related Sanskrit ślokas, or showing Ayurvedic herbs alongside corresponding verses. Below are practical ways to design servlet collaboration, with code examples and recommended best practices.

Design approaches (overview)

  • Database-first linking: Store relationships (story_id ↔ shloka_id) in the database and let any servlet query the DB.
  • Shared DAO / Connection Pool: Centralize database logic into a shared DAO layer used by all servlets.
  • ServletContext attributes: Share application-wide read-only data (like small lookup maps) via ServletContext.
  • RequestDispatcher include/forward: Compose pages from multiple servlets/JSPs on the server side.
  • RESTful servlets / AJAX: Expose servlet endpoints (JSON) so modules can call each other asynchronously from the browser.
  • Distributed caching / message brokers: For large-scale apps, use Redis or Kafka for shared cache and events.

1. Database-first linking (schema)

-- stories table
CREATE TABLE stories (
  id INT AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(255),
  content TEXT
);

-- shlokas table
CREATE TABLE shlokas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  devanagari TEXT,
  transliteration VARCHAR(500),
  meaning TEXT
);

-- linking table (many-to-many)
CREATE TABLE story_shloka (
  story_id INT,
  shloka_id INT,
  PRIMARY KEY (story_id, shloka_id),
  FOREIGN KEY (story_id) REFERENCES stories(id),
  FOREIGN KEY (shloka_id) REFERENCES shlokas(id)
);

With this schema, any servlet can query related shlokas for a story:

2. Shared DAO (single place for DB access)

public class SharedDAO {
    private DataSource dataSource; // configured with connection pool (HikariCP, Tomcat JDBC, etc.)

    public SharedDAO(DataSource ds) {
        this.dataSource = ds;
    }

    public List getShlokasForStory(int storyId) throws SQLException {
        String sql = "SELECT s.* FROM shlokas s JOIN story_shloka ss ON s.id = ss.shloka_id WHERE ss.story_id = ?";
        try (Connection con = dataSource.getConnection();
             PreparedStatement ps = con.prepareStatement(sql)) {
            ps.setInt(1, storyId);
            ResultSet rs = ps.executeQuery();
            List list = new ArrayList<>();
            while (rs.next()) {
                list.add(new Shloka(rs.getInt("id"), rs.getString("devanagari"),
                                    rs.getString("transliteration"), rs.getString("meaning")));
            }
            return list;
        }
    }

    // other shared DB methods...
}

3. Initialize DAO in a context listener and share via ServletContext

public class AppContextListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext ctx = sce.getServletContext();
        DataSource ds = createDataSourceFromConfig(ctx); // configure pool here
        SharedDAO dao = new SharedDAO(ds);
        ctx.setAttribute("sharedDAO", dao);
    }
}

Now any servlet can get the DAO:

SharedDAO dao = (SharedDAO) getServletContext().getAttribute("sharedDAO");
List shlokas = dao.getShlokasForStory(storyId);

4. Example: StoryServlet and ShlokaServlet collaboration

@WebServlet("/story")
public class StoryServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        SharedDAO dao = (SharedDAO) getServletContext().getAttribute("sharedDAO");

        Story story = dao.getStoryById(id);           // story content
        List shlokas = dao.getShlokasForStory(id); // related shlokas

        req.setAttribute("story", story);
        req.setAttribute("shlokas", shlokas);
        request.getRequestDispatcher("/WEB-INF/views/story.jsp").forward(req, resp);
    }
}

This approach renders story and its linked shlokas in one page — no extra network calls.

5. Server-side composition: RequestDispatcher include / forward

If you want modular servlets to produce parts of a page, use RequestDispatcher.include() to include output from another servlet (or JSP).

// inside StoryServlet after loading story
RequestDispatcher rd = req.getRequestDispatcher("/shlokaFragment?id=" + id);
rd.include(req, resp);  // includes the shloka list HTML produced by another servlet

6. RESTful endpoints (AJAX collaboration)

Alternatively expose a small JSON API from ShlokaServlet; the Story page can call it asynchronously to fetch related shlokas:

@WebServlet("/api/shlokas")
public class ShlokaApiServlet extends HttpServlet {
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    int storyId = Integer.parseInt(req.getParameter("storyId"));
    SharedDAO dao = (SharedDAO) getServletContext().getAttribute("sharedDAO");
    List list = dao.getShlokasForStory(storyId);
    resp.setContentType("application/json");
    resp.getWriter().write(convertToJson(list)); // use Jackson/Gson
  }
}

This decouples UI rendering from data fetching and is great for single-page apps or progressive enhancement.

7. Distributed coordination (for bigger apps)

  • Use Redis or Memcached to cache frequently-used links (story → shloka list) to reduce DB load.
  • Use message queues (RabbitMQ/Kafka) for events — e.g., when a new shloka is added, publish an event so other services can update search indexes or caches.

8. Transactional & integrity considerations

  • When modifying relations (insert story + link shlokas), use DB transactions so operations commit/rollback together.
  • Use foreign keys and cascade rules carefully — prefer explicit deletes and logging for heritage content.

9. Security & cultural sensitivity

  • Validate and sanitize inputs to avoid SQL injection (always use PreparedStatement).
  • Limit who can add/modify heritage content (role-based access).
  • Log edits for provenance and cite original sources for each shloka/story.
  • Respect transliterations — store original script (Devanagari) and transliteration separately.

10. Best practices summary

  1. Centralize DB access in a shared DAO with a connection pool.
  2. Use ServletContext for application-wide read-only data and initialization.
  3. Prefer DB relationships for core linking (story ↔ shloka) and use caching for performance.
  4. Offer both server-side rendering (include/forward) and JSON APIs for flexibility.
  5. Always use transactions and proper logging when updating linked heritage content.

Tip: Start simple — design the schema and a shared DAO first. Add caching or event-driven components once the core functionality is stable.

Post a Comment

Thanks for comment.

Previous Post Next Post