I have tried a websocket sample code as below, my browser is supporting HTML 5 websocket, but the sample code below always prompt "Close" in the javascript. What happen to the code?
websocket.java
#WebServlet("/websocket")
public class websocket extends WebSocketServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("welcome to websocket 2");
response.getWriter().flush();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
#Override
protected StreamInbound createWebSocketInbound(String arg0,
HttpServletRequest arg1) {
return new TheWebSocket();
}
private class TheWebSocket extends MessageInbound
{
private WsOutbound outbound;
#Override
public void onOpen( WsOutbound outbound )
{
this.outbound = outbound;
System.out.println("socket opened!");
}
#Override
public void onTextMessage( CharBuffer buffer ) throws IOException
{
try
{
outbound.writeTextMessage( CharBuffer.wrap( "abc testing".toCharArray() ) );
System.out.println("Message sent from server.");
}
catch ( IOException ioException )
{
System.out.println("error opening websocket");
}
}
#Override
protected void onBinaryMessage(ByteBuffer arg0) throws IOException {
// TODO Auto-generated method stub
}
}
}
index.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Index</title>
<script type="text/javascript">
var ws = null;
function startWebSocket() {
if ('WebSocket' in window)
ws = new WebSocket("ws://localhost:8080/web_test/websocket");
else if ('MozWebSocket' in window)
ws = new MozWebSocket("ws://localhost:8080/web_test/websocket");
else
alert("not support");
ws.onmessage = function(evt) {
alert(evt.data);
};
ws.onclose = function(evt) {
alert("close");
};
ws.onopen = function(evt) {
alert("open");
};
}
function sendMsg() {
ws.send(document.getElementById('writeMsg').value);
}
</script>
</head>
<body onload="startWebSocket();">
<input type="text" id="writeMsg"></input>
<input type="button" value="send" onclick="sendMsg()"></input>
</body>
</html>
When I connect to "http://localhost:8080/web_test/websocket", I got correct message which is "welcome to websocket 2". And my index.jsp file is in the root directory after web_test. So, my deployment should be fine, but somewhere is wrong. I just cannot figure it out.
Comment or remove these two methods from your servlet code and then try web sockets working fine.If these two present in the servlet , websocket is going to close state
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("welcome to websocket 2");
response.getWriter().flush();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
Related
I am having a Servlet which I am using to fetch the image from Database and display image to frontend.
Servlet:
#WebServlet("/jsp/DisplayImage")
public class DisplayImage extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
int id = Integer.parseInt(request.getParameter("userId"));
User query = new User();
//fetch user details
.......
//write user photo to response
response.reset();
response.setContentType("image/.*");
OutputStream out = response.getOutputStream();
out.write(user.getPhoto());
out.close();
} catch (Exception e) {
.......
}
}
This servlet is working fine. Now I want to create a rest api which will call this Servlet and return the user photo:
#GetMapping("displayImage")
public void getDisplayImage(#RequestParam("userId") final Integer userId) {
//TODO call DisplayImage servlet and return user photo
}
I solved this by redirecting to my servlet
#GetMapping("displayImage")
public void getDisplayImage(#RequestParam("userId") final Integer userId,
HttpServletResponse response) throws IOException {
String displayImageUrl="https://localhost:8443/app/jsp/DisplayImage?userId="+userId;
response.sendRedirect(displayImageUrl);
}
I am getting HTTP Status 404 - /ShowForm this error pls help me to solve this.
ShowForm.html
<form action = "/ShowForm" method = "post" enctype="multipart/form-data" >
Name: <input type = "text" name = "name" /><br>
File: <input type = "file" name = "file" /><br>
<input type = "submit" value = "submit" name = "submit">
</form>
ShowForm.java
#WebServlet("/ShowForm")
public class ShowForm extends HttpServlet {
private static final long serialVersionUID = 1L;
public ShowForm() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
response.setContentType("text/plain");
PrintWriter pw = response.getWriter();
ServletInputStream sis = request.getInputStream();
for(int i = sis.read();i != -1;i = sis.read())
{
pw.print((char)i);
}
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
Here I am using Annotation so I have not map in web.xml.
Following Google's pagespeed advice I would like the minify the HTML responses of my Spring application. I don't mean GZip, I mean removing comments and whitespace from HTML before it is sent down the wire.
I would like to do this dynamically and not in my templates. My templates contain many comments that are useful but should not be part of the response.
Following is my controller;
#Controller
public class IndexController {
#GetMapping("/")
public ModelAndView index() {
Data data = ....
return new ModelAndView("index", data);
}
}
I managed to do this by adding a javax.servlet.Filter component that is using com.googlecode.htmlcompressor into Spring
First the Filter;
#Component
public class HtmlFilter implements Filter {
protected FilterConfig config;
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException {
ServletResponse newResponse = response;
if (request instanceof HttpServletRequest) {
newResponse = new CharResponseWrapper((HttpServletResponse) response);
}
chain.doFilter(request, newResponse);
if (newResponse instanceof CharResponseWrapper) {
String text = newResponse.toString();
if (text != null) {
HtmlCompressor htmlCompressor = new HtmlCompressor();
response.getWriter().write(htmlCompressor.compress(text));
}
}
}
}
and relevant CharResponseWrapper;
class CharResponseWrapper extends HttpServletResponseWrapper {
protected CharArrayWriter charWriter;
protected PrintWriter writer;
protected boolean getOutputStreamCalled;
protected boolean getWriterCalled;
public CharResponseWrapper(HttpServletResponse response) {
super(response);
charWriter = new CharArrayWriter();
}
public ServletOutputStream getOutputStream() throws IOException {
if (getWriterCalled) {
throw new IllegalStateException("getWriter already called");
}
getOutputStreamCalled = true;
return super.getOutputStream();
}
public PrintWriter getWriter() throws IOException {
if (writer != null) {
return writer;
}
if (getOutputStreamCalled) {
throw new IllegalStateException("getOutputStream already called");
}
getWriterCalled = true;
writer = new PrintWriter(charWriter);
return writer;
}
public String toString() {
String s = null;
if (writer != null) {
s = charWriter.toString();
}
return s;
}
}
Works fantastically. Converts an html this ugly;
<!DOCTYPE HTML>
<html>
<head>
<title>
A Simple
<!-- Test-->
HTML Document
<!-- Test-->
</title>
</head>
<body>
<p>This is a very simple HTML document</p>
<!-- Test-->
<p>It only has two<!-- Test--> paragraphs</p>
<!-- Test-->
</body>
</html>
into this;
<!DOCTYPE HTML> <html> <head> <title> A Simple HTML Document </title> </head> <body> <p>This is a very simple HTML document</p> <p>It only has two paragraphs</p> </body> </html>
Basically my goal for this page I'm working on is for users to type in a stock symbol and this information goes to a post method and send back the data to put on the same html/jsp page. I have been able to get this to work where the form leads to another JSP page, but that has to be a separate page, I'd like to be able to stay on the same page and have the info come up. If you have a resource that could teach me how to deal with this problem, I would appreciate that just as much as a solution. I have been using the Gradle Build Tool.
Here is the form(in index.jsp):
<h1>Search Stock</h1>
<form method="POST" action="DataPage.jsp">
<input type = "text" name = "Symbol">
<input type = "submit" name = "getData">
</form>
Here is the functioning JSP code(DataPage.jsp):
<%
String Ticker = request.getParameter("Symbol");
PrintWriter write = response.getWriter();
if((Ticker == null)){
String message = "Please enter a stock symbol";
write.println(message);
}else{
try{
Company object = Serializing.getCompany(Ticker);
object.updateData();
write.println("data last added" + object.getLastUpdate());
write.println(object.getSentiment());
}catch(NullPointerException x){
Company object = Serializing.getCompany(Ticker);
}
}%>
Here is the servlet I tried writing(DataServlet.java), I have very little experience with servlets, I scavenged this from different sources and questions on stackoverflow:
package Default;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Created by Ceyer on 9/3/2015.
*/
#javax.servlet.annotation.WebServlet(name = "DataServlet", urlPatterns = ("/"))
public class DataServlet extends javax.servlet.http.HttpServlet {
private static final long serialVersionUID = 1L;
public DataServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
String Ticker = request.getParameter("Symbol");
if ((Ticker == null)||Ticker.trim().isEmpty()) {
String message = "Please enter a stock symbol";
request.setAttribute("data", message);
getServletContext().getRequestDispatcher("/login.jsp").forward(request, response);
} else {
PrintWriter write = response.getWriter();
try {
Company object = Serializing.getCompany(Ticker);
object.updateData();
request.setAttribute("data", object.getSentiment() + "updated last" + object.getLastUpdate());
getServletContext().getRequestDispatcher("/login.jsp").forward(request, response);
} catch (NullPointerException x) {
Company object = Serializing.getCompany(Ticker);
request.setAttribute("data", "We do not have info on this stock");
getServletContext().getRequestDispatcher("/login.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
If you want to use only one page and with a servlet, I think you can use session and response.sendRedirect() to do it.
This is index.jsp page
<h1>Search Stock</h1>
<form method="POST" action="DataServlet" onsubmit="dataCheck()">
<input type="text" name="Symbol">
<input type="submit" value="getData">
</form>
<%
if(session.getAttribute("data") != null) {
out.print("<p>" + session.getAttribute("data"));
session.removeAttribute("data");
}
%>
<script>
function dataCheck() {
if(document.getElementsByName[0].value == ""){
alert("Symbol is null!");
return false;
}
return true;
}
</script>
This is DataServlet class
public class DataServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String Ticker = request.getParameter("Symbol");
Company object = Serializing.getCompany(Ticker);
if (object != null) {
object.updateData();
request.getSession().setAttribute("data", object.getSentiment() +
"updated last" + object.getLastUpdate());
} else {
request.getSession().setAttribute("data", "We do not have info on this stock");
}
response.sendRedirect("index.jsp");
}
}
I am uploading files (of different content types) using Apache fileupload API as follows:
FileItemFactory factory = getFileItemFactory(request.getContentLength());
ServletFileUpload uploader = new ServletFileUpload(factory);
uploader.setSizeMax(maxSize);
uploader.setProgressListener(listener);
List<FileItem> uploadedItems = uploader.parseRequest(request);
... saving files to GridFS using the following method:
public String saveFile(InputStream is, String contentType) throws UnknownHostException, MongoException {
GridFSInputFile in = getFileService().createFile(is);
in.setContentType(contentType);
in.save();
ObjectId key = (ObjectId) in.getId();
return key.toStringMongod();
}
... calling saveFile() as follows:
saveFile(fileItem.getInputStream(), fileItem.getContentType())
and reading from GridFS using the following method:
public void writeFileTo(String key, HttpServletResponse resp) throws IOException {
GridFSDBFile out = getFileService().findOne(new ObjectId(key));
if (out == null) {
throw new FileNotFoundException(key);
}
resp.setContentType(out.getContentType());
out.writeTo(resp.getOutputStream());
}
My servlet code to download the file:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uri = req.getRequestURI();
String[] uriParts = uri.split("/"); // expecting "/content/[key]"
// third part should be the key
if (uriParts.length == 3) {
try {
resp.setDateHeader("Expires", System.currentTimeMillis() + (CACHE_AGE * 1000L));
resp.setHeader("Cache-Control", "max-age=" + CACHE_AGE);
resp.setCharacterEncoding("UTF-8");
fileStorageService.writeFileTo(uriParts[2], resp);
}
catch (FileNotFoundException fnfe) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
}
catch (IOException ioe) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
}
However; all non-ASCII characters are displayed as '?' on a web page with encoding set to UTF-8 using:
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
Any help would be greatly appreciated!
Apologies for taking your time! This was my mistake. There is nothing wrong with the code or GridFS. My test file's encoding was wrong.
resp.setContentType("text/html; charset=UTF-8");
Reason: only content type, together with a binary InputStream are passed on.
public void writeFileTo(String key, HttpServletResponse resp) throws IOException {
GridFSDBFile out = getFileService().findOne(new ObjectId(key));
if (out == null) {
throw new FileNotFoundException(key);
}
resp.setContentType(out.getContentType()); // This might be a conflict
out.writeTo(resp.getOutputStream());
}