I'm trying to learn how to write simple servlets to use with a Raspberry Pi.
I want to control the board I/O via web.I'm using the Pi4J library which is a wrapper for the WiringPi C library.It works when I use it to blink a led locally so I assume that I'm doing something wrong coding my servlet.
This is the code I wrote:
package com.luca.servlet;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.gpio.PinState;
public class MyServlet extends javax.servlet.http.HttpServlet {
private GpioController gpio=GpioFactory.getInstance();
private GpioPinDigitalOutput redLed=gpio.provisionDigitalOutputPin(RaspiPin.GPIO_23,PinState.LOW);
private GpioPinDigitalOutput greenLed=gpio.provisionDigitalOutputPin(RaspiPin.GPIO_22,PinState.LOW);
private GpioPinDigitalOutput blueLed=gpio.provisionDigitalOutputPin(RaspiPin.GPIO_21,PinState.LOW);
private GpioPinDigitalOutput[] pins=new GpioPinDigitalOutput[]{redLed,greenLed,blueLed};
#Override
public void doGet(javax.servlet.http.HttpServletRequest request,javax.servlet.http.HttpServletResponse response) throws java.io.IOException {
java.io.PrintWriter print=response.getWriter();
print.write("<body>"+
"<p> Choose a color! </p>"+
"<form action=\"first\" method=\"POST\">"+
"<input type=\"submit\" name=\"button\" value=\"red\"/>"+
"</form>"+
"<form action=\"first\" method=\"POST\">"+
"<input type=\"submit\" name=\"button\" value=\"green\"/>"+
"</form>"+
"<form action=\"first\" method=\"POST\">"+
"<input type=\"submit\" name=\"button\" value=\"blue\"/>"+
"</form>"+
"</body>");
}
public void doPost(javax.servlet.http.HttpServletRequest request,javax.servlet.http.HttpServletResponse response) throws java.io.IOException {
java.io.PrintWriter pw=response.getWriter();
String act=request.getParameter("button");
switch(act) {
case "red":
togglePin();
redLed.high();
pw.write("<p>the led is red!</p>");
break;
case "green":
togglePin();
greenLed.high();
pw.write("<p>the led is green</p>");
break;
case "blue":
togglePin();
blueLed.high();
pw.write("<p>the led is blue!</p>");
break;
}
}
private void togglePin() {
for (GpioPinDigitalOutput pin : pins)
if (pin.isHigh()) pin.toggle();
}
it compiles fine and I manually deploy it inside tomcat,with the deployment descriptor and all.
But when I connect it says to me that the resource is unavailable.
If I remove the GPIO related code it works fine.
Can someone please help me out? Google searching doesn't seem to help
You need to set an Url Pattern in order to access to your servlet methods like POST and GET.
For example use:
#WebServlet("/raspberryServelt")
public class MyServlet extends javax.servlet.http.HttpServlet {
...
And then access to the servlet methods doing a POST or GET request...
For example doing a get to:
localhost:8080/yourWebAppName/raspberryServelt
Will work...
You must put in your project the pi4j libraries in path WEB-INF/lib
Related
I'm using the sample spring-petclinic Spring Boot app for a demo I'm building. I'm trying to do something that seems super basic, but am struggling (I'm a Java n00b).
Here's the sample app: https://github.com/spring-projects/spring-petclinic
Essentially I want to display the server hostname on the welcome page of the website.
In the WelcomeController.java file (spring-petclinic/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java) I have the following:
package org.springframework.samples.petclinic.system;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
class WelcomeController {
#RequestMapping("/")
public String welcome() {
return "Hello from " + System.getenv("HOSTNAME") + String.format("%n");
}
}
All I have replaced is the return value from return "welcome" to what you see above.
The build completes and I can run the application, but the page loads with the following error:
Something happened...
Error resolving template "Hello from d7710dcc2456 ", template might not exist or might not be accessible by any of the configured Template Resolvers
I've played around with model.addAttribute and adding additional public String blocks, but am a little out of my depth! Any ideas?
When you return a String value from a controller method with #RequestMapping, spring will resolve the string value from
configured view template. So return "welcome" resolves the welcome.html inside resources/templates/ directory.
When you replace it with return "Hello from " + System.getenv("HOSTNAME") + String.format("%n")
it will look for the template with name "Hello from " + System.getenv("HOSTNAME") + String.format("%n")
As this is not present inside resources/templates/, it gives error.
Change your controller like this:
#GetMapping("/")
public String welcome(Model model) {
model.addAttribute("hostname", System.getenv("HOSTNAME") );
return "welcome";
}
And change your welcome.html like this,
<h1>Hello from <span th:text="${hostname}">hostname</span></h1>
UPDATE - after edit the question
To get hostname of running machine, try the following
import java.net.InetAddress;
import java.net.UnknownHostException;
String hostname;
try {
InetAddress ia = InetAddress.getLocalHost();
hostname = ia.getHostName();
} catch (UnknownHostException e) {
e.printStackTrace();
}
//assuming your thymeleaf template file called 'welcome'
model.addAttribute("hostname", hostname);
return "welcome";
And in your template file
<h1>Hello from <span th:text="${hostname}">hostname</span></h1>
I am a complete new t servlet can someone plz tell me what is wrong with my code;i am trying to name input from user in a textbox and then display welcome :"text entered by user in textbox"
here is my code
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
// Extend HttpServlet class
public class myprogramme extends HttpServlet {
public void service(HttpServletRequest req,HttpServletResponse res)throws ServletException,IOException {
res.setContentType("text/html");
PrintWritter out=res.getWritter();
String name=req.getParameter("txtname");
out.println("<b>< font size=8 color="red">" +"welcome:"+ </font> "</b>"+name);
}
}
name of the textbox is txtname which i am storing in name variable
To answer your specific question, you need to escape your String literal (the double quotes surrounding red) and you didn't quote the font close tag (but you could collapse it to a single HTML String) like -
out.println("<b><font size=8 color=\"red\">Welcome:</font></b>" + name);
That being said, this is not a good way to write Java Servlet today. Because it uses presentation in the Servlet.
Edit It's getWriter(), change this
PrintWritter out=res.getWritter();
to
PrintWriter out=res.getWriter();
True, it is not the best way to do it, but I would suggest you to do like below for you to learn it easily:
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
String name = req.getParameter("txtname");
StringBuilder sb = null;
try {
sb = new StringBuilder();
sb.append("<b>< font size='8' color='red'>");
sb.append(" Welcome : " + name + " </font></b>");
out.println(sb.toString())
} catch (Exception e) {
e.printStackTrace();
}
}
I haven't test it, hope you can get an idea..
I've tried this question before with little success but that's probably my fault so I'll be as specific as possible!
Part A)
I have a compiled java class which returns a hello world string. The source code for this file is below. After configuring the web.xml setting I am able to get good results from a browser pointing at localhost. This is working exactly as planned.
Part B)
I have an HTML landing page with a single link in it which, when pressed will read a local text file and replace content within it. This is also working exactly as planned.
Part A means I am able to have a client call a server-side java class file and get outputs. Part B means I am able to replace one part of a webpage after a button has been pressed.
My question, from this point is quite straight forward. I would like to merge the two concepts so that when the link from part B is pressed the text updated will reflect the 'hello world' result set from Part A.
Thanks in advance.
Part A Code:
package mypkg;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<!DOCTYPE html>");
out.println("<html><head>");
out.println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
out.println("<title>Hello, World</title></head>");
out.println("<body>");
out.println("<h1>Hello, world!</h1>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}
Part B Code
<p id="mySentence">
Click here to update the page.
When you click the link, this content will be replaced.</p>
<script type="text/javascript">
var http = createRequestObject();
function createRequestObject() {
var objAjax;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer"){
objAjax = new ActiveXObject("Microsoft.XMLHTTP");
}else{
objAjax = new XMLHttpRequest();
}
return objAjax;
}
function getNewContent(){
http.open('get','newcontent.txt');
http.onreadystatechange = updateNewContent;
http.send(null);
return false;
}
function updateNewContent(){
if(http.readyState == 4){
document.getElementById('mySentence').innerHTML = http.responseText;
}
}
</script>
I have a very simple JavaFX Controller with a simple Username, Password and Logon button.
What I want to do is when the user clicks Logon, I want the disable the inputs - which I do in code with:
this.gridPanelLogon.setDisabled(true);
And - this works but my issue is - it appears to be threaded, in that after this call I then make a JerseyClient call to a web REST service - and once that code completes it then updates the UI and disables the gridPanel. But what I would like is for the gridPanel to first disable THEN to call and it seems the UI is only updated after all the code runs (not right when it hits the line of code above).
If I explained this poorly I apologize, and I'd be happy to help clarify more but was hoping maybe someone has experienced this and could either help explain why or a work around. I also tried one other work around, putting a change listener to the gridPanel's disabled property - this didn't work and resulted in the same delay as mentioned above.
Any help would be greatly appreciated - and thanks!!
Don't run client => server calls on the JavaFX application thread, instead run them in their own thread via a Task or Service.
Thank you again to jewelsea - he answers many of these JavaFX questions so well. I wanted to share this solution, which in my testing works well for my application. I was making a Jersey-Client REST request, and was placing this inside my JavaFX application (without creating a separate class extending javafx.concurrent.Service).
So what I've done below is provide the solution that worked well for me, taking into account the links jewelsea provided above. This Service class will return a ClientResponse object after successfully POSTing to the url provided. I have tried to provide more notes about this in comments below.
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
/**
* This Service class will make REST calls to a given URL,
* with a JSON encoded request string.
*
* OnSucceeded will return a ClientResponse object - will be
* null if an exception occurred - if no exception is the
* ClientResponse result of the Jersey-Client call.
*/
public class JerseyClientPostService extends Service<ClientResponse> {
private StringProperty url = new SimpleStringProperty();
private StringProperty json = new SimpleStringProperty();
public JerseyClientPostService() {
super();
}
public JerseyClientPostService(String url, String json) {
super();
this.url.set(url);
this.json.set(json);
}
public final String getUrl() {
return this.url.get();
}
public final String getJson() {
return this.json.get();
}
public final void setJson(String json) {
this.json.set(json);
}
public final void setUrl(String url) {
this.url.set(url);
}
#Override protected Task<ClientResponse> createTask() {
final String _url = getUrl();
final String _json = getJson();
return new Task<ClientResponse>() {
#Override protected ClientResponse call() {
Client client = Client.create();
WebResource webResource = client.resource(_url);
ClientResponse response;
try {
response = webResource.type("application/json").post(ClientResponse.class, _json);
}
catch (ClientHandlerException che) {
System.err.println("ClientHandlerException connecting to Server: "+che.getMessage());
return null;
}
catch (Exception ex) {
System.err.println("Exception getting response Json: "+ex.getMessage());
return null;
}
return response;
}
};
}
}
Hello everyone and thanks in advance.
This is a last ditch effort to figure out what the problem is or find a better solution.
I am using JSP filter to filter web access to a tomcat web server.
I have a client, a server and the filter.
The client and the filter open up sockets the the server receives them.
I heard that opening up a server socket in a JSP files is a no-no but I cannot think of a better way to make it send a string to the server software, if you know any please do tell
But the problem on hand is that when the page is filtered it only send the string initially and not anytime after that
I have the socket opened in the filter and the receiver in the server program is in a thread so it should be taking and printing the string when it is received.
All of my code is zipped in here, you will need tomcat to run.
http://www.easy-share.com/1904209945/JNetProtect.zip
I'm really sorry for the length and complexity of this question, please if there is any better way to do this do speak up,
From your explanation it looks to me, that you are lacking some significant concepts. Please excuse me if it sounds offensive to you.
JSP page is processed on the server, which means if you are opening up a socket in your JSP it doesn't mean client is opening the socket.
However, can't you use command pattern, probably using Servlet Filter, to direct your request to a particular Command object and then do your socket stuff there.
Well I didn't get any exceptions,
But what would you suggest I do with this filter so I can do an outSide.println() in the DoFilter()?
import java.net.*;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public final class IEFilter implements Filter
{
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
ServerSocket fs;
String browser = "";
String blockInfo;
String address = request.getRemoteAddr();
if(((HttpServletRequest)request).getHeader ("User-Agent").indexOf("MSIE") >= 0)
{
browser = "Internet Explorer";
}
if(browser.equals("Internet Explorer"))
{
BufferedWriter fW = new BufferedWriter(new FileWriter("C://logs//IElog.rtf"));
blockInfo = "Blocked IE user from:" + address;
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE>");
out.println("This page is not available - JNetProtect");
out.println("</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("<center><H1>Error 403</H1>");
out.println("<br>");
out.println("<br>");
out.println("<H1>Access Denied</H1>");
out.println("<br>");
out.println("Sorry, that resource may not be accessed now.");
out.println("<br>");
out.println("<br>");
out.println("<hr />");
out.println("<i>Page Filtered By JNetProtect</i>");
out.println("</BODY>");
out.println("</HTML>");
// outSide.println("Blocked and Internet Explorer user");
fW.write(blockInfo);
fW.newLine();
fW.close();
} else {
chain.doFilter(request, response);
}
}
public void destroy()
{
outsocket.close();
outSide.close();
}
public void init(FilterConfig filterConfig)
{
try
{
Socket outsocket;
PrintWriter outSide ;
outsocket = new Socket("Localhost", 1337);
outSide = new PrintWriter(outsocket.getOutputStream(), true);
}catch (Exception e){
System.out.println("error with this connection");
e.printStackTrace();
}
}
}