Why am I getting nullpointer error? - servlets

To retrieve cookies from browsert, I wrote a simple function dispcookies(). When I compile, I got nullpointerException and then I just copied that code from dispcookies() and put in processRequest() that time I didn't get the error why it happens.
HttpServletRequest request;
HttpServletResponse response;
PrintWriter out=null;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try {
out = response.getWriter();
String name=request.getParameter("name");
String phone=request.getParameter("phone");
Cookie cname=new Cookie("name",name);
Cookie cphone=new Cookie("phone",phone);
response.addCookie(cname);
response.addCookie(cphone);
out.println("here ok");
dispcookies ();
}
catch(Exception E)
{
out.println(E);
}
}
void dispcookies () throws IOException
{
Cookie[] cookies;
Cookie cookie;
cookies=request.getCookies();
if(cookies!=null)
{
for(int i=0;i<cookies.length;i++)
{
cookie=cookies[i];
out.println("cookie name"+cookie.getName());
out.println("cookie name"+cookie.getValue());
}
}
else
{
out.println("no foumd cooke ");
}
}

At void dispcookies () you are trying to access to a property of the attribute request. WARNING: This request IS NOT THE SAME that the input parameter of the processRequest method. dispcookies doesn't have visibility over these input parameter, only can see the attribute HttpServletRequest defined at the beginning of the class and this attribute has not been initialized so every access to it will cause a null pointer exception.
If you want to access to the processRequest' request input parameter you must change the dispcookies signature to accept this object as input parameter and use it.
By the way:
cookies=request.getCookies();
if(cookies!=null) {
for(int i=0;i ...
could cause a null pointer exception because Cookies[] can be not null but empty and you are accessing to its zero position without checking the emptyness of the array.

Related

use of getsession() in http sessions

How come the following code snippet always enters the else block?
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out=response.getWriter();
request.getRequestDispatcher("link.html").include(request, response);
HttpSession session=request.getSession();
if(session!=null){
String name=(String)session.getAttribute("name");
out.print("Hello, "+name+" Welcome to Profile");
}
else{
out.print("Please login first");
request.getRequestDispatcher("login.html").include(request, response);
}
out.close();
}
from java doc getSession() Returns the current session associated with this request,
or if the request does not have a session, creates one.
In your code
HttpSession session=request.getSession();
It will check for current session associated with request and if there is not any,then it is going to create one.
So the check if(session!=null){ will always be true.
If you want to check that if session is present then only return HttpSession object else return null,then you can use one overloaded version of this method
HttpSession session=request.getSession(false);
See Also
JavaDoc getSession()
JavaDoc getSession(boolean)

Cannot call sendRedirect() after downloading PDF

I saw many questions like the one I am asking, but they are not exactly about what I am looking for.
I am using Command pattern, and want to create PDF-file and download it. Creating is perfect, but when I want to download it, it's starts downloading and throws an exception.
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
org.apache.jasper.JasperException: java.lang.IllegalStateException: getOutputStream() has already been called for this response
java.lang.IllegalStateException: getOutputStream() has already been called for this response
Here is my code from Command Pattern
#Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException, AppException {
String fontPath = request.getServletContext().getRealPath(AppConstants.FONT_PATH);
DBManager db = DBManager.getInstance();
String ticketCode = request.getParameter("ticketCode");
String place = request.getParameter("place");
int amountTickets = Integer.valueOf(place);
String flightName = Encoding.encoding(request.getParameter("flightName"));
User user = (User) request.getSession().getAttribute("client");
String locale = (String) request.getServletContext().getAttribute("currentLocale");
db.updateFlightTickets(flightName, --amountTickets);
///////create pdf document and represent it to the byte array
ByteArrayOutputStream baos =ReportCreator.createReport(locale, fontPath, ticketCode, place, user,
db.getFlightByName(flightName));
response.setContentType("application/pdf");
response.setContentLength(baos.size());
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition","attachment; filename=\"Ticket\"");
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
return Path.SUCCESS;
}
Here is my "success page", sorry but can not add more, not enough reputation
<fmt:message key="success_jsp.label.success" />
And here is my servlet code
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
process(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
process(request, response);
}
private void process(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String commandName = request.getParameter("command");
Command command = CommandContainer.get(commandName);
String forward = "";
try {
forward = command.execute(request, response);
} catch (AppException ex) {
request.setAttribute("errorMessage", ex.getMessage());
}
if (forward.equals(Path.SUCCESS)) {
response.sendRedirect(forward);
} else {
request.getRequestDispatcher(forward).forward(request, response);
}
}
Part of code in JSP, where click is calling the servlet
<td><button><fmt:message key="welcome_jsp.submit.buy_ticket" /></button></td>
How can i avoid it?
The exception says you are trying to working with the request/response once you redirect it or viceversa, and it's not valid.
Once you redirect a request, you cannot do anything else with the request/response, so getting the output stream and writing something to it is completely insane.
It's true about vice-versa situation, writing something and then redirect it will cause the browser will ignore the response data, or exception on server as I'm guessing you got.(but it depends on container)
So you either do not redirect the browser, or provide the pdf file with the target servlet/cgi where you are trying to redirect.
=================
And your current situation/problem:
Server sets the content-length, content-type,... and starts to write down some stream to the browser, since you haven't set any status, container will set default 200 OK which indicates there is some right response for the request.
Then browser will get some data(the pdf file) as 200 OK data(and consider it done), now how would you redirect the user once the response is almost done?!!?!!?!
I still do not understand why do you like to redirect a request when it's almost closed? you like to redirect the user after download complete? you cannot.

Filters not working properly

I made two filters for my auction web application. I implemented two filters, the first which performs simple logging operations, and the second, which check if the user is authorized to access a particular resource.
The troubles is that These filters work correctly only the first time I connect to the website. Infact it displays the name of the the user in the toolbar, and this happens only if you logged in correctly. Afterwards, I log out and I repeat the process, but the second filter does not work at all.
I put println statements to check if the filters are actually executed, but it isn't the case. The first filter works constantly. The strange part arises when I change the xml mapping. Infact, when I take the mapping out for both filters, the first filter continues working! I went nuts all day yesterday trying to understand this.
Weirder yet, If I rewrite the xml mapping for the filters, they work both for the first log in process, but then, once I log out and repeat the operation, the log in filter doesnt work anymore. To make my web application I am just JAVA7, netbeans 7.2 and Tomcat 7. I fear that this may be a bug with the Netbeans IDEA, but I am not sure.
The xml mapping is the following:
<web-app version="3.0" 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">
<filter>
<filter-name>FiltroLoggingFumettopoli</filter-name>
<filter-class>Filtri.FiltroLoggingFumettopoli</filter-class>
</filter>
<filter-mapping>
<filter-name>FiltroLoggingFumettopoli</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter>
<filter-name>FiltroLogin</filter-name>
<filter-class>Filtri.FiltroLogin</filter-class>
</filter>
<filter-mapping>
<filter-name>FiltroLogin</filter-name>
<url-pattern>/Registrato/*</url-pattern>
<servlet-name>IlMioConto</servlet-name>
<servlet-name>Vendi</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>**
Here is the first filter which does the logging in the log fil:
private void doBeforeProcessing(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (debug) {
log("FiltroLoggingFumettopoli:DoBeforeProcessing");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
this.log(httpRequest.getRemoteHost()+" is trying to access page: "+httpRequest.getRequestURL()+
" il "+TimeUtility.ottieniDataOra()+". "+filterConfig.getFilterName());
System.out.println("FILTRO FILE DI LOG----> LOGGING OCCURED IN LOG FILE: "
+httpRequest.getRequestURL()+" il "+TimeUtility.ottieniDataOra()+". "+filterConfig.getFilterName());
}
private void doAfterProcessing(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (debug) {
log("FiltroLoggingFumettopoli:DoAfterProcessing");
}
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
doBeforeProcessing(request, response);
Throwable problem = null;
try {
chain.doFilter(request, response);
} catch (Throwable t) {
problem = t;
t.printStackTrace();
}
doAfterProcessing(request, response);
if (problem != null) {
if (problem instanceof ServletException) {
throw (ServletException) problem;
}
if (problem instanceof IOException) {
throw (IOException) problem;
}
sendProcessingError(problem, response);
}
}
here is the filter which checks if it is an authorized user who wants access to the resources that are contained in the Registrato folder, and a few servlets:
public class FiltroLogin implements Filter
{
private FilterConfig filterConfig = null;
public void init(FilterConfig filterConfig)
{
this.filterConfig = filterConfig;
}
public void doFilter(ServletRequest request,ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpSession sessione = httpRequest.getSession();
ServletContext sc = filterConfig.getServletContext();
String filterName = filterConfig.getFilterName();
String servletPath = "Servlet path: " + httpRequest.getServletPath();
String url ="";
Utente user = null;
user = (Utente) sessione.getAttribute("utente");
if(user == null){
Cookie[] cookies =httpRequest.getCookies();
String email = CookieUtility.ottieniValoreCookie(cookies, "userCookie");
if(email.equalsIgnoreCase("")){
System.out.println("FILTRO LOGIN----->NESSUN COOKIE TROVATO!");
System.out.println("FILTRO LOGIN----->SERVLET CONTEXT: "+sc.getContextPath());
url ="/MostraInserzioni";
httpResponse.sendRedirect(sc.getContextPath()+url);
return;
}
else{
System.out.println("FILTRO LOGIN----->COOKIE TROVATO: "+email);
user = UtenteSql.cercaUtente(email);
System.out.println("FILTRO LOGIN----->UTENTE TROVATO: "+user.getUsername());
sessione.setAttribute("utente", user);
String salutoUtente = "Benvenuto "+user.getNome();
sessione.setAttribute("messaggio", salutoUtente);
}
}
else
System.out.println("FILTRO LOGIN----->USER FOUND: "+user.getUsername());
sc.log(httpRequest.getRemoteHost()+" cerca di accedere alla risorsa: "+httpRequest.getRequestURL()+
" il "+TimeUtility.ottieniDataOra()+". "+filterConfig.getFilterName());
System.out.println("FILTRO FILE DI LOG----> LOGGING OCCURED IN LOG FILE: "
+httpRequest.getRequestURL()+" il "+TimeUtility.ottieniDataOra()+". "+filterConfig.getFilterName());
chain.doFilter(request, response);
}
public void destroy()
{
filterConfig = null;
}
}
Simply user = sessione == null ? null : (Utente) sessione.getAttribute("utente"); and after else { just: sessione = httpRequest.getSession(true); Prevents holding sessions for non-users. – Joop Eggen yesterday
HttpSession sessione = httpRequest.getSession(false);
if (sessione == null) {
System.out.println("FILTRO LOGIN----->USER NOT FOUND IN SESSION!");
– Salvatore Servodio 44 mins ago
Then I checked the cookies. If I find the cookie i need i simply create a new session and put the USER info in the session , otherwise i simply redirect to the login page

Servlet: proper way to redirect to index versus show view in doGet() method

Given this doGet implementation:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getParameterMap().isEmpty()) {
// DAO initialized in init() method
Collection<User> users = resource.getUsers();
if (users != null){
HttpSession session = request.getSession();
session.setAttribute("users", users);
}
request.getRequestDispatcher("/WEB-INF/users/index.jsp").forward(request, response);
}
else {
String name = request.getParameter("name");
// DAO initialized in init() method
User user = resource.getUser(name);
if (user == null){
request.setAttribute("message", "Unknown user: " + name);
request.getRequestDispatcher("/WEB-INF/errors/404.jsp").forward(request, response);
}
else {
HttpSession session = request.getSession();
session.setAttribute("user", user);
request.getRequestDispatcher("/WEB-INF/users/show.jsp").forward(request, response);
}
}
}
Questions:
Is request.getParameterMap().isEmpty() the preferred way to test for the presence of parameters?
Is there a way to infer the views' location (/WEB-INF/users/) from the either the Servlet's context or an annotation?
Is request.getParameterMap().isEmpty() the preferred way to test for the presence of parameters?
Yes, it is. But this is not the right solution for your particular case. Your code will fail if the enduser supplied an arbitrary parameter with other name than name, causing the parameter map to be not empty and thus enter the block which expects the name parameter. You should really explicitly check the request parameter name itself.
String name = request.getParameter("name");
if (name == null) {
Collection<User> users = resource.getUsers();
// ...
}
else {
User user = resource.getUser(name);
// ...
}
Is there a way to infer the views' location (/WEB-INF/users/) from the either the Servlet's context or an annotation?
Use a MVC framework (recommended) or homebrew one (not recommended, unless 100% internal/private/hobby and thus for pure learning purposes).

How to send data via HTTP get in Java?

So, I am going to connect to a servlet via an iphone and use HTTP. I am actually developing a multiplayer game and would like to know how I can send specific data to the iphone via HTTP get in java (doGet). I am using libcurl on the iphone (cocos2d-x).
Here is how my code is set up:
size_t write_data(void* buffer, size_t size, size_t nmemb, void *data)
{
//do stuff with data
}
//main or some init method
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl)
{
char *data = "hi imma get=yeah";
curl_easy_setopt(curl, CURLOPT_URL, "http://whatever.com");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
CCLOG("WELP BETTER DO SOMETHING ERROR");
}
curl_easy_cleanup(curl);
}
So, what I would like to know is how I can use the response in the doGet method in java to send a string to that write_function defined above? As in, what do I do with response parameter in the doGet method?
For reference here is the doGet method:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
System.out.println("GET METHOD CALLED");
}
So, now what do I do with that response to pass some data to the write_function?
Thanks, for any and all input!!
By using response's Writer, as shown below.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// tell response what format your output is in, we select plain text here
response.setContentType("text/plain;charset=UTF-8");
// ask the response object for a Writer object
PrintWriter out = response.getWriter();
try {
// and use it like you would use System.out. Only, this stuff gets sent
//to the client
out.println("GET METHOD CALLED");
} finally {
// housekeeping: ensure that the Writer is closed when you're ready.
out.close();
}
}
In some cases it's easier to use a Stream. That's also possible but you can never have both the Writer and the OutputStream open simultaneously.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/plain;charset=UTF-8");
// ask the response object for an OutputStream object
OutputStream os = response.getOutputStream();
try {
// output some stuff, here just the characters ABC
os.write(new byte[]{65,66,67});
} finally {
os.close();
}
}
If you want to know more, there are loads of tutorials about servlets available on the web, including the Servlet chapter of the official Java EE tutorial on oracle.com

Resources