I'm having a spot of bother with a uni assignment where I am trying to display data from a cassandra database on a JSP through a servlet. Basically I am getting a null pointer exception when I try to use get methods on the class storing a user's information for a profile page.
The code below is the part of the JSP that requests the servlet send an object that holds the current user's details. When looking in the debugger it seems it gets the username without any problems but the request for Profile Details returns an empty object whereas it should be populated by information from the database.
<%
String Username=null;
LoggedIn lg = (LoggedIn) session.getAttribute("LoggedIn");
Username = lg.getUsername();
ProfileDetails pd= new ProfileDetails();
pd = (ProfileDetails) request.getAttribute("Profile");
if (pd!=null)
{
String forename= pd.getForename();
String surname=pd.getSurname();
String email=pd.getEmail();
%>
This next segment of code is the method in the servlet which calls the method which returns an object populated with the user's details.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// processRequest(request, response);
HttpSession session=request.getSession();
LoggedIn lg = (LoggedIn)session.getAttribute("LoggedIn");
String username=lg.getUsername();
User us = new User();
us.setCluster(cluster);
ProfileDetails pd= new ProfileDetails();
pd = us.GetUserDetails(pd, username);
request.setAttribute("Profile", pd);
RequestDispatcher rd = request.getRequestDispatcher("Profile.jsp");
rd.forward(request, response);
}
I'm fairly sure that the issue I'm having is based in one of these two blocks of code but at the minute I'm stumped. So any help would be appreciated greatly.
If anyone is feeling really enthusiastic about helping here is a link to my project for cloning on GitHub https://github.com/BrodieRoss/Instagrim.git
P.s. sorry if any of my explaining here sounds a bit like nonsense, I'm pretty new to web development.
You have to approach a more MVC version of your web app.
I saw that you have written some getters (voids) but it is better if you write and some setters methods for this class.
Then you have not to forward the servlet to your jsp but redirect it using:
HttpServletResponse.sendRedirect(String Location)
or
HttpServletResponse.sendRedirect("/your/new/location.jsp")
Before redirecting you have to set the attributes you want to this object. For accessing these attributes you use the same variables that your are using on the class. For displaying them in a jsp file you have to use jstl lib. Check more here:
https://www.tutorialspoint.com/jsp/jsp_standard_tag_library.htm
This tutorial might help you:
https://docs.oracle.com/cd/E15919_01/wlp.1032/e14254/developuserprofiles.htm
User us = new User(); I presume relates a "cluster" of information that is part of the server instance ?, of I see no variable declared or assignment call of any relevant form for "cluster" itself,
though/and too (et tu) I would say also "database" (as you say/wrote) means the "server configuration running instance information and SERVER-environment-variables, globals e.t.c." of the Java J2EE server in this does not have an extra configured set of "connections" to another server program (e.g. MySQL Potgre ...) requiring java drivers and connection pools associated.
Its a wonder it compiled, however, something may be a "static" variable and requires casting to a non static context to be fed to a method or variable.
Can you look through that better now?
The information would be better fed through JSP beans with some state (just a thought)
Of java integration and java compatible drivers for "Cassandra"(Driver interface instance and thread alike MySQL querying and connecting driver systems)...
http://cassandra.apache.org/doc/latest/getting_started/drivers.html?highlight=drivers
Related
I'm writing an HTTP servlet (Hosted on Amazon Elastic Beanstalk) that serves as an application server for my Android app. My application will request data from my servlet, which will in turn pull from the database (SimpleDB).
Since my client requests may be frequent, I wanted to implement a cache on my servlet that will cache the requested data so as to cut down on database reads. Currently, I just initialize a "ServerCache" object as a member variable of my servlet. ServerCache contains lists for cached data, and I populate these as I go.
Looks something like this.
public class ServerCache {
/**
* ServerCache is responsible for caching data on the server.
* Create several data structures on the server to cache buy/sell listings as listing objects.
* For now, we will be able to cache the entirety of the database contents.
* -ES
*
* Only one ServerCache should ever be made, at the init() of this server
*/
private List<BuyListing> listbl; //What is the danger of having this public vs. private
private List<SellListing> listsl;
public String BLlastError;
public String SLlastError;
public ServerCache()
{
this.listbl = new ArrayList<BuyListing>();
this.listsl = new ArrayList<SellListing>();
this.BLlastError = "Initialized";
this.SLlastError = "Initialized";
} //Setters and getters ommitted
And it is initialized here
public class HelloWorld extends HttpServlet {
private SimpleDBConnect SDB; // contains functions for accessing database
private ServerCache Cache;
//Various Constants
private static final String BUY_LISTINGS_DOMAIN = "BuyListings";
private static final String SELL_LISTINGS_DOMAIN = "SellListings";
private static final String USER_ID_DOMAIN = "UserIDs";
private static final String MESSAGES_DOMAIN = "Messages";
public HelloWorld() {
super();
SDB = new SimpleDBConnect();
SDB.createConnection();
Cache = new ServerCache();
Cache.setListbl(SDB.getAllBL());
Cache.setListsl(SDB.getAllSL());
updateSDBStatus();
updateServletStatus("Initialized");
updateCacheStatus();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.getOutputStream().println("Servlet Works \n SimpleDB Status:" + SDB.dbConnectStatus + "\n \n SDB log: " + this.SDBStatus + "\n \n Servlet log: " + this.ServletStatus
+ "\n \n Buy Cache Status: " + this.BLCacheStatus + "\n \n Sell Cache Status: " + this.SLCacheStatus);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// ... Some code ommitted, the following is a relevant part of how I handle request for data
if (packet.getHeader() == Constants.BL_REQUEST || packet.getHeader() == Constants.SL_REQUEST)
{
MsgStruct temp = new MsgStruct();
if (packet.getHeader() == Constants.BL_REQUEST){
temp.setHeader(Constants.BL_REQUEST);
Type listOfTestObject = new TypeToken<List<BuyListing>>(){}.getType();
String s = gson.toJson(Cache.getListbl(), listOfTestObject);
temp.setPayload(s);
receivedString = gson.toJson(temp);
}
Is there any reason why caching a version of the data on my servlet will be a bad idea? This is just my stab in the dark, as nobody has ever taught me what to do in this case. I'm aware that concurrency is an issue, but I dont think it should matter in this case?
Thanks
Adding a cache into the program will complicate it a little bit, specifically when you want to modify the data. In this case, the database and the cache should always have the same data, no matter what GET or POST requests are received that may or may not write to the database.
A problem you may run into is how to keep the cache in sync with the database. It will be crucial to always update the cache when writing to the database, and make sure that when you fulfill a request with the cache, that you return the same data as is contained in the database. You did say that you're only caching data requested, but if data is ever written back to the database, you will have to check that cached data is also updated.
You mentioned that you'll only instantiate one instance of the class. It might make more sense to follow the singleton pattern for the cache, see the Wikipedia page http://en.wikipedia.org/wiki/Singleton_pattern for more information. Basically, this causes the cache to initialize itself and make sure no other code can make another instance. The constructor will be private, and you would write a getInstance() method to have the cache return the instantiated ServerCache object.
The reason I'm going this route is because there's always a possibility that you will write another servlet that needs to access the database, and it will be difficult to give it cache access without making the cache a singleton (not to mention multithreading issues associated with multiple reads).
Another thing to remember, your cache will take up RAM on the server. Caching trades of RAM usage for access time, and depending on your plan, you may or may not have a lot of that to spare. It's also a real possibility that you'd just replicate your entire database in RAM, defeating its purpose. You would spend a bunch of processing time making sure you update the database but never actually use it. So again, if you see an improvement in responsiveness, I see no problem with it, as long as you manage it well.
To effectively use a cache, you'd have to keep a strict limit on the number of cached objects, getting rid of objects that aren't used much, keeping only the ones that are accessed very frequently. A final point I want to make is that I noticed your cache is using ArrayLists. Those aren't the most efficient data structures for searching unsorted data. A database is made for data storage, so the database most likely has a more efficient storage system anyway, which in your case would make a cache only useful for very small amounts of frequently accessed but seldom modified data.
I have a problem in a system that I am working as back-end support for. I need to write a test that calls one of the classes handeling the communications with our database so I can log out what it actually returns.
System setup
Our system is developed in Java and deployed on a weblogic server. It consists of many parts that I will not go into detail on here. But the interesting part is that we have a class acting as an adapter for our database. We call it "CMAdapter" and it is an implementations of IBM Content Manager specific code to handle interaction with our database. In this class we have a methid called fetchAct() that take one object with search parameters as an argument and it returns the result of the search. In this case it returns one act. The code we have is running on a weblogic server, that has an IBM Information Integrator for Content installed so that it can communicate with IBM Content Manager that is installed and running on a different server. The system is deployed on the server using a .ejb and a few .jar files.
The problem
I have recieved a case stating that for some acts the users are not recieving the full act as expected but only parts of it. The system itself displays no errors and the documents are present in the database. So what I am trying to do is write a simple test program that calls this "CMAdapter" with a predetermined set of searchcriteria so that I may log out the return of the search.
My question
How can I make a freestading class with a main() method and run it on the server? I need to make a call to the CMAdapter.fetchAct() method in a way so it runs on the server like any normal query?
My test class
public class TestHamtaAkt
{
public static void main(String[] args) throws BasException
{
Log LOG = Log.getLog(TestHamtaAkt.class);
// Get the CMAdapter
CMAdapter cmadapter = new CMAdapter();
// Create empty instance of our query object
SokVO sokvo = new SokVO();
// Put a value to search for in our query object
AttributVO aktAttribut = new AttributVO();
aktAttribut.setNamn(DLAKonstanter.AKT_KORT_R_KOD);
aktAttribut.setVarde("090084831574");
sokvo.aktAttributLista().add(aktAttribut);
// do the search an recieve the answer
AktVO aktvo = cmadapter.hamtaAkt(sokvo);
// log out the result
LOG.debug("main", "Akten som hämtades: " + aktvo.toString(), null);
}
}
Thanks to all for reading my question. It appears I have found the answer to my own question. It was hiding with a collegue of mine. The answer to my problem was, to be able to access the server deployed code, I need to get the JNDI context from my webserver and from that do a jndi lookup for the class I need.
I still have some problems making the connection but that is problably just my configurations that are off. I now know how I get a simple java class to make a call to a deployed class on a server.
here is the code I am currently using to get the context from the WLS server:
private static InitialContext getWLSContext(String url) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, WLS_CONTEXT_FACTORY);
//env.put(Context.PROVIDER_URL, "t3://" + host + ":" + port);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
This is my code for geting the class I need.
public static EJBObject getRemote(String url, String jndiname, Class homeClass, AppserverTyp typ) throws Exception
{
Object obj = getWLSContext(url).lookup(jndiname);
EJBHome home = (EJBHome) javax.rmi.PortableRemoteObject.narrow(obj, homeClass);
Class homeBase = home.getClass();
Method m = homeBase.getMethod("create", (Class[])null);
EJBObject remote = (EJBObject) m.invoke(home, (Object[])null);
return remote;
}
I hope this helps someone with a similar problem to move forward. Like I said I have still to actually get this code working for me but my this is the answer to my initial question on how to make a call to a deployed method from an external class.
Basically I have the model of my project set up this way:
ModelFolder
-----src
-----bin, etc.
-----PropertiesFolder1
--------File1.properties
--------File2.properties, etc.
-----PropertiesFolder2
--------File1.properties
--------File2.properties, etc.
-----MainPropertiesFile1.properties
-----MainPropertiesFile2.properties
I am trying to use it with my View, which is a Dynamic Web Project, and I got the properties files to finally load in my Web Project after changing
foo.load(new FileInputStream("foo.properties"));
to
foo.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("foo.properties"));
and exporting the project to a JAR file, which I then included in WEB-INF/lib. However, I had to add another method to the Model, and when I tried testing that method, the Model was not able to read my properties file. I know that I can use FileInputStream with the full path to get the properties file working in the Model and the View, but are there any alternatives?
I don't want to keep changing the full path every time I switch computers (I use H:\username\...\Java\Workspace at work, whereas at home it's just C:\Java\Workspace).
I also don't want to have to move my properties files to different folders; and finally I don't want to change the way I load the properties file every time I test my Model or my View.
Is there a way to accomplish this?
This is driving me crazy, I've tried all of the following:
try
{
foo.load(this.getClass().getResourceAsStream("foo.properties"));
//foo.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("foo.properties"));
//foo.getClass().getResourceAsStream("foo.properties");
//foo.load(new FileInputStream("foo.properties"));
} catch (IOException ex)
{
al.logIntoProgrammerLog(ex);
}
All of those lines either work in the model or the view. Is there any way I can call those properties files via a relative path in the model, and then somehow properly connect the model with the view so that all the files are found and loaded?
Any help would be greatly appreciated; I am new to Java, so I might be missing something really simple. Thank you.
EDIT:
Sorry for not clarifying this, the Model is a Java Project, whereas the View is a Dynamic Web Project running on local Tomcat Server v6.0.
Better (I hope) explanation:
My View has a LoginServlet with the following doPost method:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String username = request.getParameter("usernameField");
String password = request.getParameter("passwordField");
ActivityLogger al = new ActivityLogger();
LoginController l_c = new LoginController();
//loginUser method will call my UserStorage class and
//will return true if UserStorage finds the User with those credentials in the db
//UserStorage is using a prepared sql statement stored in a properties file to find the User
//That properties file is not being read unless I specify the full path to it.
//Both Login and UserStorage are in the Model
if(l_c.loginUser(username, password))
{
//take user to welcome page
}
else
//display error
}
Thanks again
Take a look at this thread for possible solutions for sharing a .properties file. But I would suggest that you review this approach to see if it's really what you want. More specifically, if your .properties file contains SQL queries, then are you sure you need it in your View? Sounds like you may want to make a clean separation there.
If you are in a web application, you should be able to get the path (relative path in the context of the webapp, so it will work on any machine) by using the ServletContext's getResourceAsStream(). For example, if you wanted to get the path from your servlet's doGet() method:
public void doGet(HttpServletRequest request, HttpServletResponse response) {
InputStream in = getServletContext().getResourceAsStream(<path>);
}
where <path> would be the relative path to your .properties file (i.e. /WEB-INF/foo.properties, or wherever that properties file is located... look in your deployment folder to find out for sure)
But in re-reading your post it seems like perhaps your "Model" is not a webapp and your "View" is a webapp? Maybe you could clarify whether these are two different applications - and possibly one being a webapp running within a servlet container (i.e. Tomcat, Glassfish, etc) and one being a standalone app? If that's the case then this is more of a shared file issue than a 'cannot find resource' issue. A bit of clarification about the nature of your application(s) would help steer the correct response...
Anyone know how to retrieve a contentStream from a DLFileEntry (http://docs.liferay.com/portal/6.0/javadocs/com/liferay/portlet/documentlibrary/model/DLFileEntry.html) using an httpservlet?
I tried using DLFileEntry.getContentStream() but it fails giving me the error
com.liferay.portal.security.auth.PrincipalException: PermissionChecker not initialized
I solved in part that problem setting hardcode my userId:
long userId=2
PrincipalThreadLocal.setName(userId);
User user = UserLocalServiceUtil.getUserById(userId);
PermissionChecker permissionChecker;
permissionChecker = PermissionCheckerFactoryUtil.create(user, false);
PermissionThreadLocal.setPermissionChecker(permissionChecker);
The problem of this solution is how to get the real userId, and how happen if the user is a guest?
I tried Long.parseLong(req.getRemoteUser()); but fail also.
DLFileEntryLocalServiceUtil.getFile(userId, fileEntryId, version, incrementCounter)
gives you the File. Did you try using this?
If you're using Liferay 6.1 then the following code will get you a InputStream for the That DLFileEntry.
InputStream inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(fileEntry.getUserId(), fileEntry.getFileEntryId(), fileEntry.getVersion());
Howwever the error you're getting is seems to be due you not authenticating with Liferay before making this call to the server.
How are you calling this code?
Please use PermissionThreadLocal.getPermissionChecker() to get the permissionChecker object of the current logged in user with current state. If the user is guest, still you will get the permissionChecker object.
-Felix
Currently my J2EE Application supports these below countries
MessagesBundle_en_GB.properties (United Kingdom )
MessagesBundle_en_US.properties (United States )
MessagesBundle_it_IT.properties (Italy )
MessagesBundle_pt_BR.properties (Brazil )
MessagesBundle_sv_SE .properties (Sweden)
So i made a properties files for all these countries above and defined the Key value pairs in it .
I am using Resource Bundle for this concept .
And the way i will be accessing the key name is this way
bundle.getString("userName"));
bundle.getString("Mobile"));
Now my question is ,
How can i set the Locale value inside the JSP Page , because the user might belong any of the country as mentioned above
Please let me know , thank you very much
// This one is hardcoded , how can i set this dynamically ??
ResourceBundle bundle = ResourceBundle.getBundle("MessagesBundle", Locale.UK);
use ResourceBundle.getBundle(BUNDLE_NAME).getString(key); to access the Strings.
when updating the Default Locale e.g. via Locale.setDefault(<REQUIRED_LOCALE>); clear the Resourcebundle cache: ResourceBundle.clearCache();
the next call of ResourceBundle.getBundle(BUNDLE_NAME).getString(key); should the return the localized String of the chosen Locale.
The simplest way to do it is to implement HttpFilter. Call it for example LocaleHttpFilter. It should be mapped to/*` in your web.xml, so it will be called every time the request arrives to your application.
The filter will discover your request and decide what should be the current locale. It may base its decision on URL parameters, HTTP headers, GeoIP lookup etc. Once it decided about the locale it should call:
Locale.setDefault(locale)
Then you can use
ResourceBundle.getBundle("MessageBundle").getString("hello");
at any place in your code. This line will return value of string "hello" according to the current locale that was set into the filter.
First thing first: you may use ResourceBundle.getBundle(Locale) in your back-end code. However, you should never use this in the JSP Page directly. You should use JSTL instead. Now, let's get into details.
There are two reasons why it is not necessary the good idea to use ResourceBundle directly. One is related to this:
<%
try {
ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
} catch (MissingResourceException mre) {
// LOG THIS!
}
%>
This looks pretty ugly, doesn't it? That's because you have to beware of MissingResourceException that will be thrown if there is no bundle for base name you are looking for. To make matters worse, the same exception might be thrown if there is no key in the given scenario:
rb.getString("key");
So you also need to take this into account:
<%
try {
rb.getString("key");
} catch (MissingResourceException mre) {
// LOG THIS!
}
%>
How does it look?
Of course you can derive from ResourceBundle and override these methods so they won't throw an exception, but this is substantially more work than just this:
<fmt:setLocale value="fr_CA" scope="session"/>
<fmt:bundle basename="com.taglib.weblog.Greeting">
<fmt:message key="com.taglib.weblog.Greeting.greeting">
This is the reason you should use JSTL with JSP. Read more about how to use JSTL for i18n in this article.
Now, your original question was about language negotiation (W3C term), or Locale detection if you prefer. How to do that in JSP application?
The easiest and most typical scenario is to read the contents of HTTP's Accept-Language header. In Java Servlet world that means calling ServletRequest's getLocale() or getLocales() method and assign to variable in HttpSession object, which is accessible from JSP page. If you wonder how to access HttpSession on the servlet side, there is a getSession() method.
That works if you have direct access to Servlet. If you don't you need to create (or assign existing) Locale filter which will do all that for you. As you may imagine, this is fairly common scenario. That's the reason people already written (long time ago) necessary classes. You can find in few frameworks, let me notably mention Spring Framework.
I know it might sound strange, but if you are looking for simple solution, learning and using common web framework (i.e. Spring MVC) is better that re-inventing the wheel. I know that learning curve might be a bit steep, but it is worth it.