How to send data via HTTP get in Java? - http

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

Related

how to get filter httpservletresponse outputstream error message in filter

I am using spring 4 and filters I got some error response in servletResponse. It contains outputstream with an error message.
How can I get this error message in Outputstream and audit to my app?
try{
filterChain.doFilter(wrappedRequest, servletResponse);
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
LOGGER.info("Basic Authenticate HttpServletResponse code {}"+httpServletResponse.getStatus());
httpServletResponse.getOutputStream();
// I need to read this outputstream, its contains error message.?
}catch(Exception e){
LOGGER.error("Error Basic Authenticate Error :{}", e);
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
AtomicInteger statusCode = new AtomicInteger(httpServletResponse.getStatus());
Response response = ResponseUtil.populateResponse(statusCode, e.getMessage().toString(), 0);
httpServletResponse.sendError(httpServletResponse.getStatus(), e.getMessage());
auditService.updateRestAuditRecord(auditId,StringUtils.EMPTY, response);
}
The key is the HttpServletResponseWrapper decorator class. Adapt these steps to your specific needs:
Fully read the stream you want to audit to something like a byte buffer.
Do your auditing task.
Extend HttpServletResponseWrapper, override getOutputStream() and return an extension of ServletOutputStream that streams your byte buffer.
Pass the HttpServletResponseWrapper to the next downstream filter in the chain.

Why am I getting nullpointer error?

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.

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.

Can I force the browser to download the PDF file instead of opening it?

So this is the code I have:
public class PdfDownloaderServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws ServletException, IOException {
httpServletResponse.setContentType("application/pdf");
ServletContext servletContext = httpServletRequest.getServletContext();
InputStream inputStream = servletContext.getResourceAsStream("/WEB-INF/classes/pdfs/x.pdf");
int read;
byte[] bytes = new byte[1024];
OutputStream os = httpServletResponse.getOutputStream();
while ((read = inputStream.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
}
}
and it works just fine.
However when I click the link that invokes this method, the browser will open the file, but I want the browser to directly download the file. How can I achieve this?
Thanks.
If you want the browser to download as attachment, you need to say so using the Content-Disposition header field. See http://greenbytes.de/tech/webdav/rfc6266.html#disposition.type, disposition type "attachment".

Resources