I am new to java so excuse my lame questions:)
I am trying to build a web service in Java NetBeans 6.1 , but I have some troubles with configuration parameters ( like .settings in .net).
What is the right way to save and access such settings in a java web service.
Is there a way to read context parameters from web.xml in a web method?
If no what are the alternatives for storing your configuration variables like pathnames ?
Thank you
Is there a way to read context parameters from web.xml in a web method?
No, this is not easily done using the out-of-the-box. The Web Service system (JAX-WS) has minimal awareness of the Servlet engine (Tomcat). They are designed to be isolated.
If you wanted to use the context parameters, your web service class would need to implement ServletContextListener and retrieve the desired parameters in the initialization parameter (or save the context for later use). Since the Servlet engine and JAX-WS would each have different instances of the object, you'd need to save the values to a static member.
As Lars mentioned, the Properties API or JNDI are your best bets as they're included with Java and are fairly well-known ways to retrieve options. Use Classloader.getResource() to retrieve the Properties in a web context.
If you are using servlets, you can configure parameters in web.xml:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
These properties will be passed in a ServletConfig object to your servlet's "init" method.
Another way is to read your system's environment variables with
System.getProperty(String name);
But this is not recommended for other than small programs and tests.
There is also the Properties API if you want to use ".properties" files.
http://java.sun.com/javase/6/docs/api/java/util/Properties.html
Finally, I believe looking up configurations with JNDI is pretty common when developing modern web service applications, Netbeans and app containers have pretty good support for that. Google it.
MessageContext ctx = MessageContext.getCurrentThreadsContext();
Servlet wsServlet = (Servlet) ctx.getProperty(HTTPConstants.MC_HTTP_SERVLET);
ServletConfig wsServletConfig = wsServlet.getServletConfig();
ServletContext wsContext = wsServletConfig.getServletContext();
I think the correct answer is ... as always ... "It depends". If you are just running a small implementation with a single server then it depend much on the WS technology you want to use. Some make the servlet context and the context-params easy to access, others don't, in which case accessing properties from a properties file may be easier. Are you going to have an array of servers in a load balanced environment with high traffic where updating the setting for all servers must be instant and centralized in-case of fail-over? If that's the case then do you really want to update the config files for all servers in the farm? How do you synchronize those changes to all those servers? Does it matter to you? If you're storing path-names in a config file then you probably intend to be able to update the path-names to another host in case certain host goes down ("\file_server_host\doc_store" --> "\backup_file_server_host\doc_store") in which case is may actually be better to fail-over using DNS instead. There are too many variables. It really depends on the design; needs; scale of the app.
For simplicity sake, if you just want a simple equivalent of a .settings file then you want a .properties file. Here is an example where I have recently used this in a project: https://github.com/sylnsr/docx4j-ws/blob/master/src/docx4j/TextSubstitution.java
Related
I have an application hosted and it uses many different servlet paths. It seems Jetty (that GAE uses) creates a new session for every context path in the request URL.
Example:
abc.appspot.com/
abc.appspot.com/path2/hello
Each of those paths use two different sessions. Is there any way to prevent that? I came across the following config that can be used in the web.xml file for Jetty servers:
<context-param>
<param-name>org.eclipse.jetty.servlet.SessionPath</param-name>
<param-value>/</param-value>
</context-param>
It hasn't worked for me, am I doing it wrong or this is impossible? I've heard this is possible in Tomcat.
I'm guessing you want to share a session (data) between 2 applications and not just share the same id with different id.
If so, check spring-session which is server agnostic, and can help you to do crazy stuff
I try to secure my Java Servlet application with keycloak. All works fine but I don't like the fact that my 'keycloak.json' file is inside my release located. The reason is, if the keycloak definitions are inside my war, so I need for different installations different build processes or the same client credentials on different installations.
My idea was now to place the 'keycloak.json' outside my WEB-INF. Is this possible? Other ideas to solve this problem are also welcome.
if you check the KeycloakOIDCFilter you see there are three additional parameter.
keycloak.config.resolver
keycloak.config.file
keycloak.config.path
We are using file parameter and works like charme.
The Servlet-Filter mentioned above is not necessary.
It is enough to set a context-parameter, like #OkieOth said in his comment.
E.g. set a Parameter like this
<Parameter name="keycloak.config.file" value="MY-PATH/keycloak.json" override="false"/>
within your context (beside the for keycloak configured Valve) or a "context-param" in your web application deployment descriptor (/WEB-INF/web.xml):
<context-param>
<param-name>keycloak.config.file</param-name>
<param-value>MY-PATH/keycloak.json</param-value>
</context-param>
For more Detail about context-params, see The Context Container in section "Context Parameters".
I currently have a Jersey webapp without a web.xml. It deploys nicely, but doesn't start up until it receives its first web request.
To get the webapp to load at startup, I could create a web.xml for the webapp and give a load-on-startup tag. However, I'd strongly prefer not to make a web.xml.
Is there a way to get a JAX-RS application to load at startup without web.xml? I'll even accept a solution that is specific to Jersey and/or Tomcat.
EDIT: I would also accept a solution that loads all apps in a Tomcat instance eagerly.
EDIT: Let me give a little more information on how the app is being deployed, per a comment.
The deployment process is not sophisticated.
The App will live on an EC2 instance running Ubuntu 12.04. I'm setting up one instance of the App by hand; once it works, I will make an AMI of the app and create additional copies of it as needed.
To deploy the app on the initial instance, I'm simply copying the WAR file to /var/lib/tomcat7/webapps and restarting Tomcat. No other webapps will be running on this Tomcat instance.
If any additional information would be useful, let me know! I'll happily add it.
EDIT: For clarity's sake, this is how my webapp Application class looks, at a high level:
#ApplicationPath("/")
public class App extends ResourceConfig {
// ...
}
I'm using the Jersey-specific ResourceConfig class instead of the more general JAX-RS Application class because I'm using Jersey's built-in HK-2 to do some dependency injection.
The only way I can think of to do that is to switch to setting up the Jersey ServletContainer yourself and set its "load on startup" value to something greater than zero. You might use a ServletContainerInitializer (no relation--the naming is just a coincidence) to do it. If you happen to be using Spring, its WebApplicationInitializer offers the same mechanism with a slightly more convenient interface.
Another, rather hacky, way would be to write a class that extends ServletContainer and give it an appropriate Servlet 3.0 annotation, something like #WebServlet(value="/", loadOnStartup=1)
One solution would be to force a first request to the app by simply adding a call to curl or wget to your deployment script. It has the additional advantage of warming up any caches. And it can be used for testing if the deployment and the app really work. (Just check HTTP status code or some text on the response page...)
Dear fellow Developers,
I am working on improving my Java Web Services, and I am trying to use a more delicate way of getting the directory path of properties files in a Java Web Service.
In order to make my Java Web Application easier to be deployed on an Apache Tomcat Server, I add the following line to the web.xml file:
<env-entry>
<env-entry-name>loggerPropertyFile</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>/Some/Long/Directory/File/Path/Which/May/Change/conf/LoggerInfo.properties</env-entry-value>
</env-entry>
As the above xml code depicts, I have placed a Properties file somewhere in the local Filesystem, and I want my Web Service to initialize its logger class, based on that configuration. As you can realize this path changes every time I deploy my web service to another server.
Thus, I figured out that I may be able to use the $CATALINA_BASE property, in order to make the environment entry path smaller. How can I retrieve the CATALINA_BASE value from inside my Java Web Service's Code (how is done on Linux and how is done on Windows)??
Thank you.
try System.getProperty("catalina.base");
We want to share user validation configuration between a Java validation class (for sanity checking) and a Javascript-enabled form web interface (for usability). What's the best way to deploy this static file in our web application so that it is both available to the server-side code, and available via a URL accessed by the client?
So far I've thought of putting the file in the application root and pointing the validation class at it when it is used, and putting the file in the WEB-INF/classes directory and somehow configuring the container to serve it.
Has anyone else configured a web application like this? What did you end up doing?
Yeah. Put it in the WEB-INF/classes and have a servlet serve out the relevant portion of the validation configurations based on something like a form-id. Better yet, have the servlet transform the configuration into a JSON object and then you can simply include a script tag and start using it :)