0

I've been tasked with a modifying a jsp project (not Spring). The change is quite simple: Take a static list of links on a page and replace them with a dropdown consisting of said links. The other requirement is that the datasource for the dropdown be a properties file. They want this so that the end users of the site (internal project) can modify/remove links without having to redeploy the app. I'm a javascript guy (AngularJS, EmberJS, jQuery, etc) whose had a brief introduction to jsp about 10 or 12 years ago, so I'm quite green about it. To get my feet wet, I downloaded IntelliJ, setup a Tomcat project and got it to read and display a couple of values in a properties file. WooHoo!. It took a couple of hours of googling just to get this far. Although I've found code that will build a select using jsp, I've not found anything that shows me how to layout a properties file and read in the key/value pairs that I can use as the option/value for the select items.

Here's my properties file:

fname=Courious
lname=George

Here's the markup that displays the values:

<%@page import="java.util.Properties" %>

<%
 InputStream stream = application.getResourceAsStream("foo.properties");
 Properties props = new Properties();
 props.load(stream);
 String fname = props.getProperty("fname");
 String lname = props.getProperty("lname");
%>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
out.println(fname);
out.println(lname);
%>
</body>

And it correctly displays Curious George.

Can someone provide some guidance as to how to proceed with creating a select using a properties file? Thanks

Lazloman
  • 1,289
  • 5
  • 25
  • 50

1 Answers1

2

I would proceed this way:

  1. load the properties (like you did)
  2. fill a map (because the keys and value are easy to access with JSP-EL)
  3. set the map in a page attribute (accessible from JSP-EL)
  4. iterate through the map (with the Core JSTL)
  5. populate the option tags using key and value

Like this:

<%@ page contentType="text/html; charset=UTF-8" 
  import="java.io.InputStream, java.util.HashMap, java.util.Properties" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%
// 1. load the properties
InputStream stream = application.getResourceAsStream("foo.properties");
Properties props = new Properties();
props.load(stream);

// 2. fill a map
HashMap<String, String> linkMap = new HashMap<String, String>();
for (final String name: props.stringPropertyNames()) {
     linkMap.put(name, props.getProperty(name));
}

// 3. set the map in a page attribute
pageContext.setAttribute("linkMap", linkMap);
%>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h3>select field with map</h3>
<select name="link">

<!-- 4. iterate through the map -->
<c:forEach items="${linkMap}" var="link">
    <!-- 5. populate the option tags -->
    <option value="${link.key}">${link.value}</option>
</c:forEach>
</select>
</body>

It is bad practice to use scriptlets in JSP.
You should consider moving the code from <% ... %> inside a servlet and forwarding to the JPS.

EDIT:

JSP should be used only to present the information. The preparation, calculation, database actions, etc should be done in Servlets.
You can read more here: How to avoid Java code in JSP files?

In your case: You create a servlet, lets name it PrepareLinkList, and move the scriplet code from above there:

@WebServlet("/PrepareLinkList")
public class PrepareLinkList extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("testingThings/properties/foo.properties");
         Properties props = new Properties();
         props.load(stream);

         HashMap<String, String> map = new HashMap<String, String>();

         for (final String name: props.stringPropertyNames()) {
             map.put(name, props.getProperty(name));
         }

         // make the linkMap attribute available accross the application
         getServletContext().setAttribute("linkMap", map);
         // response.sendRedirect("dropdown.jsp");
         // or
         // request.getRequestDispatcher("dropdown.jsp").forward(request, response);
    }

}

And in the JSP stay only the presentation:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>

<h3>with map</h3>

<select name="link">
<c:forEach items="${linkMap}" var="link">
    <option value="${link.key}">${link.value}</option>
</c:forEach>
</select>

</body>

As you see the know you can run once the PrepareLinkList Servlet, and access the linkMap in all other following requests of JSP/Servlet. It reduces code repetition and it is easy to maintain.

In your case, you can run/forward/include the PrepareLinkList after the execution of one lets say UpdateLinksProperties-Servlet

Community
  • 1
  • 1
code_angel
  • 1,537
  • 1
  • 11
  • 21