How to handle classes that need web resources? - java

I'm making a project in Java where I have a class that on its initialization connects to an API to retrieve some info. Based on that info it then provides several methods to use and analyse it.
But what if the web request fails ? Or if I have some other issue. Every method will now fail because they don't have the info required
What I did is having a boolean named loadInfo, and also a public method didLoadInfo, so that the client knows the state of the object. I also add a reloadInfo method to try to reload all info, and every method throws an exception if they are called when the loadInfo variable is false. That exception is a checked exception.
Is there another better way to handle this situation ? The exception thrown by all the methods should be checked or unchecked ?
EDIT:
Is a good idea to maintain default values, but how would you let the client know that the info returned may not be up to date ? Maybe another boolean indicating the info state ?

I think in this kind of scenarios you should use REST, so that your java components will be running on web server independently.
If you UI is up and running(it could be on angular or react js or html) and have REST calls in place to call java REST API, also you can configure other API in same web project independent of REST classes and will be initialized as soon at web context is loaded( for example if you are using spring, as soon as application context is loaded).

Since you are calling other services to retrieve info, use Netflix Hysytix to handle failure gracefully with a fallback method. Obviously, you have many more options to fallback logic.
Check out the official Hystrix Library here.
If you have time, check out my article on LinkedIn.

Related

How to set session key in cookie for every request in jersey

I am using jersey for REST service. I am deploying the REST service using apache tomcat. How do i set the session key in every response.
I have tried the below piece of code
return Response.ok(response.toString(), MediaType.APPLICATION_JSON).cookie(new NewCookie("JSESSIONID", request.getSession().getId())).build();
where request is instance of HttpServletRequest. I want to is there any configuration in web.xml so that the JSESSIONID is set for every response
Generally speaking (this holds true for many frameworks!) anything you want to be used in multiple places is best done with a filter. I'm not going to show you exactly how you do it, as it is very simple and it is better for you to read the docs, but have a look here:
https://jersey.java.net/documentation/latest/filters-and-interceptors.html
You can apply these to both methods and classes, so you only need to place annotations in a couple of places.
A very useful thing for writing clean code!

Stop the deployment if any error in the servlet context listener [duplicate]

I have a ServletContextListener which performs some database management functions when my Java EE application starts. This runs in my application before JPA and other pieces of the application are started/loaded. If the database maintenance fails I am logging the errors. If the database maintenance fails the application will not function properly and I would like to halt the application.
How can I gracefully and correctly stop the application from ServletContextListener.contextInitialized?
Solution given by Viven below is close but not quite. When I throw a RuntimeException Glassfish is left in an inconsistent state where its admin console is not accessible but some process is still running and keeping port 3700 (IIOP?) open which then prevents a restart.
In your listener, catch any exceptions and use servlet context attributes to store flags or other useful information about the error. You should probably also log something to indicate that the app is non-functional.
At this point, your options may be dictated by the architecture of your app. If all requests are handled by a single controller/dispatcher servlet, it might make sense to have its init method check the context attributes and throw an UnavailableException. Just be aware that the exception only applies to the specific servlet throwing it. This makes the approach less manageable if your app contains many servlets or allows direct access to other resources.
Another option would be to create a filter that intercepts every request, checks the context attributes and then throws an exception. Other variations are certainly possible.
If your ServletContextListener throws an exception, the webapp won't load correctly and the application server may block all subsequent request (and respond with a 500 error).
It isn't exactly preventing the application to start, nor stopping the application, but it prevents any further usage of the app and could be useful in your case.
After proper verification in the spec, this behaviour isn't mandatory in the specification. The server may (not must) return 500 errors. This solution has to be used carefully, therefore.
See this Answer for a quote from the Servlet spec.

Exception design mismatch to the requirement in application

In my application, i have decided to integrate hoptoad error logging system in it. But as the application is huge, it requires a lot of manual work to call the log method present in the hoptoad class in each and every catch block. As of now, i have included the method call for error logging in few catch blocks. This is a spring, hibernate, flex, drools, maven managed application.
hoptoadUtil.logToHoptoad(throwable);
My doubt is - can i call this method globally for the application ,i.e., ask spring to call this log method in hoptoad class wherever any exception or error occurs.
Spring AOP might help you, check this link for an example
http://www.mkyong.com/spring/spring-aop-examples-advice/

EJB 3.1 remove invocation context for security purpose (ThreadLocal, ...)

I have a webapp on one Glassfish server (front-end) and an EJB 3.1 app (back-end) on another Glassfish server. The webapp communicates with the EJB 3.1 via remote invocation.
I would like to pass context data (user data i.e.) without having to define it as an input parameter of each business operation.
I have one idea, but not sure it will work: use a ThreadLocal to store data, but the ThreadLocal will only be available on one server (meaning JVM) => use the InvocationContext object and create interceptor to add user data to the ContextData Map.
What do you think about it? Any other ideas are more than welcome! ;-)
UPDATE
After first answer, I googled it a little bit and found the annotation #CallerPrincipal.
How can I set this object before the remote invocation?
The container will already handle this so you don't have to code it yourself.
In your EJB, you can access the EJBContext, which has a getCallerPrincipal() method which will give you the callers identity.

How to approach shifting a Java Swing app to a Servlet?

I want to use the Model-View-Controller template while writing my Web App. The problem is, the Model part of the code has already been written in Swing. The Model code also must require the container to call its main method before any interaction with its servlets. So is there a way for me to specify the location of the main method in the Deployment Descriptor so that the container calls the main method and compiles the code, and then, keeps it running for the entire duration the server is running without in any way restarting or recompiling the model class in between.
Try looking into load-on-startup parameter of servlet in Deployment Descriptor (DD). Precisely, it will load that particular servlet on server start-up.
Moreover, you should read about request lifecycle, request/session/application context. And you must look into JSP (or any other popular technology) for creating V of MVC. How URL mapping works.
Main method is basically work as an entry point in our application. Whereas in web application there is no particular entry point. Or if there is you can think of a welcome page. You might also want to look into welcome-file-list parameter of DD.
Cheers.
To run initialization when a web app is loaded, you can either use the servlet's init method or a ServletContextListener. You can call the main method from either of those yourself.

Categories