I am looking at using the "@Resource String ..." injection available in servlet 3.0+ containers for providing configuration parameters easily to servlets. I would like for the defaults to work and fail if the key is not present in JNDI (indicating a configuration error)
I have toyed with a simple servlet in Netbeans 8.2 with Glassfish 4.1.1 where I would like to have the userName
field, and the setFullName(String fullName)
set:
package foo;
import java.io.IOException;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "NewServlet", urlPatterns = {"/NewServlet"})
public class NewServlet extends HttpServlet {
@Resource(description="user name")
String userName;
private String fullname;
@Resource()
public void setFullName(String fullName){
this.fullname = fullName;
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet NewServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("Full name = " + fullname);
out.println("<h1>Servlet NewServlet at " + request.getContextPath() + "</h1>");
out.println("Username = " + userName);
out.println("</body>");
out.println("</html>");
}
}
// Autogenerated stuff omitted
}
Without "web.xml" the fields are just null (and no failure). I have then played around with "web.xml" to see how I could define this. The "java:comp/env/foo:NewServlet/fullName" name is what Glassfish 4.1.1 appears to create as the name for the fullName setter.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<env-entry >
<env-entry-name>java:comp/env/foo.NewServlet/fullName</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>!BAR!</env-entry-value>
</env-entry>
<env-entry >
<env-entry-name>java:comp/env/foo.NewServlet/userName</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>!USERNAME!</env-entry-value>
</env-entry>
</web-app>
This then fails with
Severe: Exception while deploying the app [WebApplication4] : Naming binding already exists for foo.NewServlet/userName in namespace {java:module/env/foo.NewServlet/userName=Env-Prop: java:comp/env/foo.NewServlet/userName@Non-Injectable Resource@java.lang.String@!USERNAME!@@, java:module/env/foo.NewServlet/fullName=Env-Prop: java:comp/env/foo.NewServlet/fullName@Non-Injectable Resource@java.lang.String@!BAR!@@}
There is nothing else but these two files in the project. Apparently I am misunderstanding something basic, but reading the Java EE tutorial and searching for suggestions did not help me. I would really like two things:
- Either not providing any hints to the @Resource-tag using the container generated defaults or just a key like "our.application.fullName".
- Fail loudly if anything is wrong, including the key-value not being present.
Suggestions? A good answer will give a 500 point bounty.