NanoHTTPD how to present variable from app - java

I play NanoHTTPD and WebServer based on it. To update any object in my code (application) I can use GET/POST method. But how can I create dynamic pages? For example I have html page on disc and it should present current temperature:
<html>
<head>
<title>My page</title>
</head>
<body>
<p style="text-align: center">Temperature: [temperature variable] </p>
</body>
</html>
How can I pass "variable temperature" from my application based on NanoHTTPD to html file and present it in browser?

You have to read the template from your disk, and replace the [temperature variable] substring with the value you want to include.
To read the file, you can use the Files class:
byte[] data = Files.readAllBytes(Paths.get("mytemplpate.html"));
String templ = new String(data, StandardCharsets.UTF_8);
To insert your temperature:
double temperature = 22.3;
String html = templ.replace("[temperature variable]", Double.toString(temperature));
And finally to send this as the response with NanoHTTPD:
return new NanoHTTPD.Response(html);
The complete program:
Foreword: Exceptions are not handled, this is just for demonstration purposes.
public class TemperatureServer extends NanoHTTPD {
// Loaded and cached html template
private static String templ;
// Value of this variable will be included and sent in the response
private static double temperature;
public TemperatureServer () {
super(8080);
}
#Override
public Response serve(IHTTPSession session) {
String html = templ.replace("[temperature variable]",
Double.toString(temperature));
return new NanoHTTPD.Response(html);
}
public static void main(String[] args) throws Exception {
byte[] data = Files.readAllBytes(Paths.get("mytemplpate.html"));
templ = new String(data, StandardCharsets.UTF_8);
ServerRunner.run(TemperatureServer.class);
}
}
For more advanced examples check out the Samples package of the NanoHttpd Github site.

Related

How to create a web service in Java that keeps push video binary data to a web page?

I have been doing researches on how to real-time stream video from a camera using Java and OpenCV. I could real-time stream the video with Java JFrame application.
Now I want to real-time stream the video on a web page. I have done researches on that. It seems that using <video> tag of HTML5 with src="blob:http://domain.name/codeabcxxxxx" is a good option.
So I've created a web service with Spring MVC framework. Below is the web service controller that handles the AJAX requests, captures the video frames from the camera and sends the AJAX response with the video frames in binary data.
import ...;
#RestController
public class GreetingController {
final static int CV_CAP_DSHOW = 700;
final static int CAMERA_ID = 0;
VideoCapture videoCapture;
Mat m;
public GreetingController() {
System.load( "C:\\opencv\\build\\java\\x64\\" + Core.NATIVE_LIBRARY_NAME + ".dll");
videoCapture = new VideoCapture(CAMERA_ID, CV_CAP_DSHOW);
m = new Mat();
videoCapture.read(m);
}
#GetMapping("/streaming")
public byte[] streaming() {
while (true) {
if (videoCapture.isOpened() && videoCapture.read(m)) {
int type = BufferedImage.TYPE_BYTE_GRAY;
if ( m.channels() > 1 ) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
BufferedImage image = new BufferedImage(m.width(), m.height(), type);
WritableRaster raster = image.getRaster();
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
final byte[] targetPixels = dataBuffer.getData();
m.get(0, 0, targetPixels);
return targetPixels;
}
}
}
}
Besides that, I've created an index.html web page as following.
<!DOCTYPE html>
<html>
<head>
<title>Start Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<video id="second-video" controls autoplay muted></video>
<video id="third-video" controls autoplay muted></video>
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
const secondVideo = document.getElementById("second-video");
const thirdVideo = document.getElementById("third-video");
const url = "http://localhost:8080/streaming";
axios.get(url).then(res => {
const content = res.data;
// Try URL.createObjectURL
const url = URL.createObjectURL(new Blob([content], {type: "video/H264"}));
secondVideo.src = url;
// Try MediaSource
const mediaSourceA = new MediaSource(url);
thirdVideo.srcObject = mediaSourceA ;
});
</script>
</html>
The client (JavaScript on the web page) sends AJAX request to the web service, after getting AJAX response, containing the video frame in binary data, from the web service, it creates an blob object and add the object to the src attribute of the <video> tag. I have tried to use URL.createObjectURL and MediaSource for two different <video> tags. Nothing works!
Result: No video showing in the <video> tags and the web service does not keep sending next video frames, due to the return statement inside the while-loop.
I miss the following knowledge:
Does the client need to keep sending AJAX requests to the web service for each video frame continuously?
or
The client sends only one AJAX request and the web service keeps sending responses with new video frames continuously?
If the client needs to keep sending AJAX requests, how does the client do that?
If the client needs to send only one AJAX request, how can the web service keeps sending responses continuously? Because with my code above, the while-loop stops due to the return statement and the streaming() method needs to use the return statement.
I kind of miss some understanding, please help me! Thanks!

Multipart POST request doesn't contain the file uploaded

I want to extend an existing application with a drag and drop file upload feature. The application is built upon Jetty + Wicket. DropzoneJS seems a good way to go. Dropzone provides all front-end work, I just have to wire it up to the back-end.
More easily said than done, as it turns out. First, I created a test application with the Wicket quickstart. I added dropzone to the HomePage:
<!DOCTYPE html>
<html>
<head>
<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script>
<link rel="stylesheet" href="https://rawgit.com/enyo/dropzone/master/dist/dropzone.css">
</head>
<body>
<form action="/upload" class="dropzone"></form>
</body>
</html>
Dropzone is simply included from its repository. On the server, I mounted a resource reference at /upload:
public class FileUploadResourceReference extends ResourceReference
{
public FileUploadResourceReference(String name)
{
super(FileUploadResourceReference.class, name);
}
#Override
public IResource getResource()
{
return new FileUploadResource();
}
}
FileUploadResource will handle processing of uploaded files:
public class FileUploadResource extends AbstractResource
{
#Override
protected ResourceResponse newResourceResponse(Attributes attributes)
{
ServletWebRequest request = (ServletWebRequest) attributes.getRequest();
try
{
MultipartServletWebRequest multipartRequest = request
.newMultipartWebRequest(Bytes.megabytes(100), "ignored");
Map<String, List<FileItem>> files = multipartRequest.getFiles();
List<FileItem> fileItems = files.get("file");
for (FileItem fileItem : fileItems)
{
saveFile(fileItem);
}
}
catch (FileUploadException e)
{
e.printStackTrace();
}
return null;
}
private void saveFile(FileItem fileItem)
{
// not implemented
}
}
Now here's the problem, when uploading files, Dropzone sends a POST-request to my http://localhost:8080/upload. The request is recognized as a multipart request, but the file parameter is absent. A null pointer exception is thrown entering the for-loop:
java.lang.NullPointerException
at com.test.FileUploadResource.newResourceResponse(FileUploadResource.java:31) ~[classes/:?]
at org.apache.wicket.request.resource.AbstractResource.respond(AbstractResource.java:629) ~[wicket-core-7.4.0.jar:7.4.0]
at org.apache.wicket.request.handler.resource.ResourceRequestHandler.respond(ResourceRequestHandler.java:105) ~[wicket-core-7.4.0.jar:7.4.0]
at org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler.respond(ResourceReferenceRequestHandler.java:108) ~[wicket-core-7.4.0.jar:7.4.0]
I can't figure out what's going on here. According to the Dropzone website, the form declaration should be fine. A bug in Dropzone perhaps? Seems unlikely. Some Jetty configuration parameter that is denying multipart form requests? Seems highly unlikely, at least I've never heard of it.
You can find full source code of my test app on GitHub.
You miss one method call - multipartRequest.parseFileNames().
You need to do it before #getFiles().
See http://wicketinaction.com/2012/11/uploading-files-to-wicket-iresource/

Jersey, HTML button calls Java method

I have to make a project for my study exam with using Grizzly server and Jersey. The server is set up and runs perfectly and uses my HTML file to create the website. Now I want to make a button that calls a Java method on click.
Here is the Grizzly server:
public static void main(String[] args) throws IOException {
URI baseUri = URI.create("http://localhost:9998");
final ResourceConfig resourceConfig = new ResourceConfig(Homepage.class);
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(baseUri, resourceConfig);
System.out.println("Starting grizzly ...");
Homepage hp = new Homepage();
hp.sayHelloInHtml();
JOptionPane.showMessageDialog(null, "Stop Server");
server.shutdownNow();
}
Here is the Homepage.java code:
#Path("")
public class Homepage {
#GET
#Produces("text/html")
public String sayHelloInHtml() throws IOException {
String content = Files.toString(new File("homepage.html"), Charsets.UTF_8);
return content;
}
public void btnClicked(){
System.out.println("Button clicked!");
}
}
And this is the homepage.html code:
<HTML>
<BODY>
<H2>
Hello World
</H2>
<button>
Click Me!
</button>
</BODY>
</HTML>
So when I click the button Click Me! I want to call the method btnClicked() in the class Homepage.
Do I have to make any type of client or something? Never worked with Jersey and we need to do it like that.
Try this in your method. on button click call action with the url /btnClicked
#Path("/btnClicked")
#GET
#Produces("text/html")
public void btnClicked(){
System.out.println("Button clicked!");
}

export to excel from web application is not working

I am having a very wierd issue and I'm hoping you can help me out
At work, we use a web application made with the framework GWT, and all the sales reports have an option to export the data to excel. It usually works fine, but the days that the report has more than about 15-20 thousand rows, the excel file only opens with the word "null" on the first cell.
Within the code, we use a JSP to send the data as html and a StringBuffer object to append all the text of the html. Here es the method that sends the html:
public void export(final String psFormat) {
manageStartOfCall();
String lsFileName = "resources/system/excel_file.jsp";
final DynamicForm loForm = new DynamicForm();
loForm.setAction(lsFileName);
loForm.setMethod(FormMethod.POST);
loForm.setCanSubmit(true);
final TextAreaItem loDataToExport = new TextAreaItem("psExcelData");
final Window loExcelWindow = new Window();
loExcelWindow.setWidth(5);
loExcelWindow.setHeight(5);
loExcelWindow.addItem(loForm);
addChild(loExcelWindow);
new Timer() {
public void run() {
cancel();
loDataToExport.setValue(moHeader.getHeaderAsExcel() + "<br><br>" + moReportGrid.getDataAsHTML());
loForm.setFields(loDataToExport);
new Timer() {
public void run() {
cancel();
manageEndOfCall();
loForm.submit();
loExcelWindow.destroy();
}
}.schedule(200);
}
}.schedule(200);
}
I've already debugged the getDataAsHTML method and the string that it returns is fine, it contains the correct HTML, however when I call the method getParameter in the JSP y returns a null value. Here the code of the JSP:
<%
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=eYumReport.xls");
String msDataToExcel = request.getParameter("psExcelData");
%>
<html>
<head>
<title>Data to excel</title>
</head>
<body>
<%=msDataToExcel %>
</body>
</html>
I may have to mention I am using this on Firefox 26, GWT 2.1, smartGWT 2.4, Windows 7 Professional and the Web application is on Windows Server 2008, mounted on Apache 6.
Any ideas why this is happening??

Applet - Unable to write file

I'm trying to write sample file from applet but is not working. Below is the code.
Applet
public class PasteImageApplet extends JApplet {
Clipboard clipboard;
Toolkit toolkit;
JLabel lbl;
public String getClipboardImageURL(String server) {
lbl.setText("pasting image");
String url = "";
try {
DataFlavor dataFlavor = DataFlavor.imageFlavor;
System.out.println(dataFlavor.getDefaultRepresentationClass());
Object object = null;
try {
object = clipboard.getContents(null)
.getTransferData(dataFlavor);
JOptionPane.showMessageDialog(null,"Image found.");
try
{
Writer output = null;
String text = "Test Write File";
File file = new File("write.txt");
output = new BufferedWriter(new FileWriter(file));
output.write(text);
output.close();
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null,"Error writing file"+ex);
return "" ;
}
//return "";
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "No image found.");
return "";
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error."+e);
return "";
}
return url;
}
public void init() {
lbl = new JLabel("");
lbl.setText("applet started");
add(lbl);
toolkit = Toolkit.getDefaultToolkit();
clipboard = toolkit.getSystemClipboard();
}
}
HTML
<html>
<head>
<title>Clipboard image demo</title>
<script type="text/javascript">
function loadApplet() {
// Deferred load to display text first
document.getElementById("applet").innerHTML = '<object id="paste-image" classid="java:PasteImageApplet.class" type="application/x-java-applet" archive="tst.jar" width="1" height="1"></object>';
}
function getImage() {
obj = document.getElementById('paste-image');
postTo = "http://localhost/PasteImageApplet/PasteImageApplet/Web/shoot.php"; // Change this to your URL
image = obj.getClipboardImageURL(postTo);
if (image) {
url = "shots/" + image;
document.getElementById("target").src = url;
document.getElementById("url").value = document.getElementById("target").src; // to get full path, hack, I know ;)
document.getElementById("container").style.display = "";
}
}
</script>
<body onload="loadApplet();">
<p>
Copy some image data to your clipboard, accept the applet (it only accesses the clipboard) and click the button :-)
See a blog post about this demo
</p>
<p>
<div id="applet"></div>
<input type="button" value="Paste it!" onclick="getImage();">
</p>
<div id="container" style="display: none;">
<input type="text" id="url" style="width: 700px;"><br />
<iframe id="target" width="700" height="400"></iframe>
</div>
</body>
</html>
I didn't get any error as well. Please advice.
That's because applets live there own sandbox, where they require special permission to perform certain operations, like read or write the disk of a client machine. Remember, applets execute within the context of the client machine, they are guests and need to follow the house rules
Check out What Applets can and cannot do for more details
An applet cannot establish a File on the server. That is not how servers work. If a server accepts uploads, it must provide specific functionality to enable that and the applet must use that functionality.
As long as the functionality to accept an upload is on the same server, the applet can remain sand-boxed.
you can see the console for applets via the (windows) taskbar, you right click the java icon(when applet is running it should appear on the lower right) and right click > open console, you can debug there, this is where the stack trace of an applet goes.

Categories