I have a device which sends a JSON message via HTTP POST, to a web server. The server receives the JSON message as payload and decodes and prints it on the web page and also sends back a 200 OK response to the post.
Now, I am trying to replicate the same with a fake Java client code to act as the device and a fake server using servlet and JSP.
The servlet code and JSP run as one project and the Java code run as another project.
I am using Eclipse and Tomcat server.
My code is as follows:
Servlet Code:
(This is saved in Java Resources > src > DefaultPackage)
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import org.json.JSONException;
import org.json.JSONObject;
#WebServlet("/HelloWorld")
public class HelloWorld extends HttpServlet {
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StringBuilder sb = new StringBuilder();
BufferedReader reader = request.getReader();
try {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
} finally {
reader.close();
}
System.out.println(sb.toString());
String api_key = null;
try {
//JSONObject jsonObj = new JSONObject(sb.toString().substring(sb.toString().indexOf('{')));
//JSONTokener t = new JSONTokener(sb.toString());
JSONObject obj = new JSONObject(sb.toString().replace("\uFEFF", ""));
System.out.println(obj.toString());
api_key= (String) obj.get("api_key");
//String node_number = (String) obj.get("node_number");
//String tag_statuses = (String) obj.get("tag_statuses");
//String voltage = (String) obj.get("voltage");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("api_key:"+ api_key+"\n");
response.setStatus(response.SC_OK);
//response.setContentType("text/html");
//PrintWriter out = response.getWriter();
//out.println("<h1>"+out +"</h1>");
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/NewFile.jsp");
request.setAttribute("api_key", api_key); // set your String value in the attribute
dispatcher.forward( request, response );
}
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
doPost(req, res);
}
}
JSP Code:
(saved in WebContent)
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<table>
<tr>
<td><%=request.getAttribute("api_key")%></td>
</tr>
</table>
</body>
</html>
Java Application Code:
import java.io.*;
import java.net.*;
import org.json.JSONObject;
public class Client {
public static void main( String [] args ) {
try
{
JSONObject jsonObj = new JSONObject("{\"api_key\" : \"rien\", \"node_number\" : \"40\", \"tag_statuses\" : [[100,\"MISSING\"]], \"voltage\": \"345\", \"location\": [42.3432,23.0098]}");
URL url = new URL("http://localhost:95/sample/HelloWorld");
URLConnection uc = url.openConnection();
HttpURLConnection conn = (HttpURLConnection) uc;
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-type", "application/json");
PrintWriter pw = new PrintWriter(conn.getOutputStream());
//pw.write(jsonObj.toString());
pw.write(jsonObj.toString());
pw.close();
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
bis.close();
int responseCode = conn.getResponseCode();
System.out.println("Response Code recieved is: " + responseCode);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Here, I would like to see the content received by the servlet to be updated on the JSP, whenever some new content appears on the servlet, maybe by refreshing the webpage.
Now, When I try to run the code, without a jsp page I am receiving the content from the application and the java application is getting a 200 status update.
But when I try to include the JSP code, the JSP will run and I get a 'null' printed on JSP, but I get the data on console of servlet and I get the following exception on Java application code (instead of a 200 status message),
java.io.FileNotFoundException: http://localhost:95/sample/HelloWorld
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at Client.main(Client.java:21)
Could someone please help me in getting the content printed on the JSP real time and to avoid the error on the Java application? What am I doing wrong here?
Thanks.
First thing I recommend you to do is to debug things not with your own client but using curl, which is stable and already tested ad nauseam.
See the following: How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
It looks like that your response is either 500 or 404 error code. I bet 500 since your server-side does not seem to be producing a 404.
Also, consider migrating both client and server to Jersey, which already solves all your problems.
https://jersey.java.net/
But if you want to stick to your implementation, it looks like the problem is on the way you are writing your client. The client thinks that you are trying to read a file (URL may also point to files, not only network URLs). Here again Jersey is your friend since, as I said before, it also has an HTTP client library.
From my personal experience with Java Servlets and JSPs the functionality of real time updating is not achievable through the method you are implementing. This is because when the request for the JSP is rendered, it will be rendered with whatever information your app contains when the request is received, then is sent to the browser. Once in the browser is all html/css, no java scriptlets, so it won't update automatically.
You can use web sockets to achieve this live-content feature or simply run a javascript function that calls the some servlet (ajax calls), retrieve the information, and change the html content.
Example of Ajax Call for email verification, used in the old days.
$.ajax(
{
url: "/validation", //URL of request
data:
{
param1: form.email.value //Parameter that will be sent.
},
async: false, // You can make it Async.
type: "POST", // Type of request.
dataType: "text", // Expected data type, might be json.
success: function(data) // If Ajax is success it will execute this function
{
if(data=="true")
{
missingStuff =" This email is already registered \n";
correoDiv.attr("class", "form-inline has-error");
}
else
{
correoDiv.attr("class", "form-inline has-success");
}
}
}
);
Another think you might want to check out it is : Socket.io,
they offer many features for realtime content.
Related
I have a simple HTML form to send a request to a REST API. It works well, when I submit, it sends the form data to API and displays the response in the browser.
<form name="theForm" action="localhost:8080/App/rest/consumeForm" method="post">
<input name="userName" value="Bob Smith" /><br/>
<input type="submit" value="submit"/>
</form>
Browser shows:
{"address": "12 First St.", "city": "Toronto"}
I would like to capture the response. Any ideas? (no ajax or javascript, just plain old Servlet or JSP please)
PART 2:
I now POST my form to a servlet I created, which handles the request and response from the REST API. It works nicely, but it needs the form data URLEncoded. Anyone know if there is a way to convert form data to such a string, or even convert form data to JSON directly?
String charset = java.nio.charset.StandardCharsets.UTF_8.name();
String userName = "Bob Smith";
String country = "Canada";
String queryString = String.format("userName=%s&country=%s"
,URLEncoder.encode(userName, charset)
,URLEncoder.encode(country, charset)
);
Can I build the above queryString dynamically?
//// send request
URLConnection connection = new URL("localhost:8080/App/rest/consumeForm").openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
try (OutputStream output = connection.getOutputStream()) {
output.write(queryString.getBytes(charset));
}
//// get response
BufferedReader apiResponse = new BufferedReader(new InputStreamReader((connection.getInputStream())));
String output;
System.out.println("\n\n\nrecieved....");
while ((output = apiResponse.readLine()) != null) {
System.out.println(output);
}
I would like to capture the response. Any ideas?
Install a servlet Filter that handles this. When it receives a request for the REST API endpoint, it can feed an HttpServletResponse to the next element in the chain that is equipped with any tooling you want. You would probably find HttpServletResponseWrapper to be a useful base class for your custom-tooled response class.
The Filter implementation might be along these lines:
public class ResponseCapturingFilter implements Filter {
private static final String SERVLET_TO_FILTER = "...";
#Override
public void init(ServletConfig config) {
// ...
}
#Override
public void destroy() {
// ...
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (((HttpServletRequest) request).getServletPath().equals(SERVLET_TO_FILTER)) {
response = new MyCapturingResponseWrapper(response);
}
chain.doFilter(request, response);
}
}
To capture the response text, you would want your wrapper to override at least getOutputStream() and getWriter() appropriately.
It turns out that submitting to a servlet using POST and communicating with the REST API using the servlet works for me. There may be better ways, but this seems relatively clean for junior developers to follow and maintain. (I'm still open to other options).
I build a queryString with the form data (req is the HttpServletRequest)
String theQueryString="domainId=1";
for(Entry<String, String[]> qsParm:req.getParameterMap().entrySet()) {
theQueryString+="&"+qsParm.getKey()+"="+URLEncoder.encode(req.getParameter(qsParm.getKey()), charset);
}
// set up connection to use as API interaction
URLConnection connection = new URL("localhost:8080/App/rest/consumeForm").openConnection();
connection.setDoOutput(true); // Triggers POST apparently
connection.setRequestProperty("Accept-Charset", java.nio.charset.StandardCharsets.UTF_8.name());
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + java.nio.charset.StandardCharsets.UTF_8.name());
// send request to API via connection OutputStream
try (OutputStream output = connection.getOutputStream()) {
output.write(theQueryString.getBytes(java.nio.charset.StandardCharsets.UTF_8.name())); // this sends the request to the API url
}
// get response from connection InputStream and read as JSON
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonMap = mapper.readTree(connection.getInputStream());
// now the response can be worked with in at least two ways that I have tried
String user1 = jsonMap.get("userName").asText();
String user2 = jsonMap.at("user").getValueAsText();
for example :
i have a js like :
$.get('Test_Controller.html',function(response){
alert(response);
});
and in my Test_Controller.html servlet i have :
request.setAttribute("test","testData");
RequestDispatcher requestDispatcher =
request.getRequestDispatcher("/test.jsp");
requestDispatcher.forward(request,response);
Question is :
why is that the response will always alert the text content of the test.jsp and not the JSON that i passed through the getWriter()
EDIT :
I need to get the :
TestData testData = new TestData();
request.setAttribute("test",testData);
using jQuery's $.get() so the page won't reload, but unfortunately when i didn't do dispatch my response object seems to be null and when i do dispatch and forward, when i alert the response it alerts the text of the page.
You want to write some information from within your servlet back to the client.
Your serlvet could look like this:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("application/json");
Writer w = response.getWriter();
w.append("... your json here ....");
}
And that's all there is (obviously wiring the servlet to your URL in web.xml). Your $.get() should see whatever you write into the writer.
Note that both what's sent (in Java) and what's received (in Javascript) are TEXT strings. You're responsible to convert your data to readable JSON on the Java side, and to interpret the text as JSON on the Javascript side. The latter can be done like this:
$.get(....., function(data) {
try {
// convert the text to JSON
data = jQuery.parseJSON(data);
} catch (e) {
alert("Problem reading data: "+e);
}
... use the JSON data ...
}
In this case the final response is coming from test.jsp because you have forwarded the request to test.jsp inside that Test_Controller.html. If you want to print that json data to test.jsp then you don't need to forward that request to test.jsp page.Otherwise you can also create that json file inside
test.jsp using scriplet tag like:
<%
request.setAttribute("test","testData");
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
String json = new Gson().toJson(test);
response.getWriter().write(json);
%>
Happy Coding!!!
Get the object in test.jsp .
<%
TestData testData = (TestData) request.getAttribute("test");
String testDataString = new GSON().toJson(testData);
out.println(testDataString);
%>
Javascipt USE $.getJSON instead of $.get
$.getJSON('Test_Controller.html',function(responseJSON){
alert(responseJSON);
var testData = responseJSON;// Then you can accesss your class values.
$.each(testData,function(key,value){
alert("Key:-"+key+": Value:-"+value");
} );
});
The problem I am trying to solve is having a javascript function that will perform some functions in sequence.
Step 1) Web client/javascript does some functions locally to the browser.
Step 2) The browser calls a java class/application on the webserver which will perform a number of tasks that only the webserver itself (not the client) can perform.
Step 3) Have the results of step two added to the webpage and displayed in the browser without reloading all the HTML
N.B. Step 2 may take several minutes and it is ok for the client to be essentially inactive during this time.
I'd appreciate any advice or walk throughs/tutorials that may be relevant.
Kind Regards
Use jQuery to perform an asynchronous HTTP request(AJAX)
function YOURFUNCTION(){
//Calls servlet
$.post('ServletName',{parameter:value,parameter2:value2,...},function(results) {
//displays results returned from servlet in specific div(resultsDiv)
$('#resultsDiv').html(results);
});
}
You need to include the jQuery library on top of your HTML file as:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
You may find more info here
Simple as that.
i hope this concise explanation will give you an overview and the understanding you expect.
PART A
SERVER SIDE
In your web server application on your server, if using Java, you are to create a Java servlet class to process data that was submitted from client browser via script or form and to provide dynamic content such as the results of a database query from the client.
Read more on Servlets from:
http://docs.oracle.com/javaee/5/tutorial/doc/bnafe.html
http://en.wikipedia.org/wiki/Java_Servlet
What is Java Servlet?
Also read more about how to register your servlet on the server (web.xml for java Projects)
Example of a servlet:
-================-
#WebServlet(name = "MyServlet", urlPatterns = {"/calculator"}, asyncSupported = true)
public class MyServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Enumeration e = request.getParameterNames(); // parsing the string from client
while (e.hasMoreElements()) {
String name = (String) e.nextElement();// eg. "command" from ajax
String value = request.getParameter(name); // eg. getSum
if (value.equals("getSum")) {
// Instantiate a java class and call the method
// that performs the addition and returns the value
Calculator calc = new Calculator();
String answer = (String) calc.getSum();
if (answer != null) {
// Set contentType of response to client or browser
// so that jQuery knows what to expect.
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
// return answer to ajax calling method in browser
out.print(answer);
out.close();
}
}
} // END While LOOP
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// include method if you call POST in you ajax on client side
}
}
a Java Class for calculations on your server path
public class Calculator {
public int getSum() {
return 10+15;
}
}
-
PART B
CLIENT SIDE – Your Browser
-======================-
You have to visit jQuery website, download and add the jQuery ajax script to your project. “jquery-ui.min.js” is sufficient for this purpose. Add this script to your html or jsp file using the following line:
<script src="resources/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript"></script>
Within your external javascript file or inline javascript include a function to call the servlet and get the sum as follows:
function getSum(){
$.ajax({
type: 'GET', // type of request to make. method doGet of the Servlet will execute
dataType: 'text', // specifying the type of data you're expecting back from the server
url: 'calculator', // the URL to send the request to. see annotation before class declaration
data: "command="+"getSum", // Data to be sent to the server (query string)
// if request fails this method executes
error:
function(e){
alert('Error. Unable to get response from server');
},
// when request is successful, this function executes
// display the data from server in an alert
success:
function(result){
if(result) {
alert(result);
}
}
});
}
I would like to call my webservice methods from pure java script code. and that code should work on mozilla browser.
This is my webservice code:
package com.example.core;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
#WebService
public class Area {
#WebMethod
public double square(#WebParam(name="side") double side)
{
return side * side;
}
#WebMethod
public double rectangle(#WebParam(name="length") double length,#WebParam(name="breadth") double breadth)
{
return length * breadth;
}
public static void main(String[] args) {
Area area = new Area();
String url = "http://localhost:8090/area"; // end point of webservice.
System.out.println(url+"?wsdl");
Endpoint.publish(url, area); // publishing the webservice
}
}
Here is my HTML file:
<html>
<head>
<meta content="utf-8" http-equiv="encoding">
<meta content="text/xml;charset=utf-8" http-equiv="Content-Type">
<script language="javascript">
function call()
{
var side = sideid.value;
var side1 = sideid1.value;
var req = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://core.codon.com/\"><soapenv:Body><web:rectangle><length>" + side+ "</length><breadth>" + side1+ "</breadth></web:rectangle></soapenv:Body></soapenv:Envelope>";
//var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
//var reqXML = xmlDoc.loadXML(req);
var xmlDoc=document.implementation.createDocument("", "", null);
xmlDoc.async=false;
xmlDoc.onload = req;
//var reqXML = xmlDoc.load(req);
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4)
{
var response = xmlhttp.responseXML;
alert(response.selectSingleNode(".//return").text);
alert("======"+response);
}
}
var soapaction = "http://core.example.com/rectangle";
xmlhttp.open("POST","http://localhost:8090/area?wsdl",true);
xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlhttp.setRequestHeader("SOAPAction", soapaction);
xmlhttp.send(req);
}
</script>
</head>
<body>
Side Length: <input type="text" id="sideid"></input>
Length: <input type="text" id="sideid1"></input>
<button onclick="call();">area of square</button>
</body>
</html>
with the above code am getting response as null. The same code working on IE but not in mozilla...
my webservice side am getting the following error
com.sun.xml.internal.ws.transport.http.server.WSHttpHandler handleExchange
WARNING: Cannot handle HTTP method: OPTIONS
Please Help me out..Thanks in advance
I would take SOAP UI, generate web service client, generate example requests, so I don't need to create SOAP envelopes from scratch. Then I would use jQuery to generate AJAX requests with the help of generated SOAP envelopes.
Another approach would be to make use of http://cxf.apache.org/docs/javascript-clients.html - you will have complete JavaScript generated that way.
You are running webservice as stand alone app on port say 'x' and the client might be on another port say 'y'
When you do a post call through y onto x the method will always be changed to options automatically. Internet standards wont allow 'posting' between different servers, I guess.
You will have to find another workaround.
How do I get an InputStream from a URL?
for example, I want to take the file at the url wwww.somewebsite.com/a.txt and read it as an InputStream in Java, through a servlet.
I've tried
InputStream is = new FileInputStream("wwww.somewebsite.com/a.txt");
but what I got was an error:
java.io.FileNotFoundException
Use java.net.URL#openStream() with a proper URL (including the protocol!). E.g.
InputStream input = new URL("http://www.somewebsite.com/a.txt").openStream();
// ...
See also:
Using java.net.URLConnection to fire and handle HTTP requests
Try:
final InputStream is = new URL("http://wwww.somewebsite.com/a.txt").openStream();
(a) wwww.somewebsite.com/a.txt isn't a 'file URL'. It isn't a URL at all. If you put http:// on the front of it it would be an HTTP URL, which is clearly what you intend here.
(b) FileInputStream is for files, not URLs.
(c) The way to get an input stream from any URL is via URL.openStream(), or URL.getConnection().getInputStream(), which is equivalent but you might have other reasons to get the URLConnection and play with it first.
Your original code uses FileInputStream, which is for accessing file system hosted files.
The constructor you used will attempt to locate a file named a.txt in the www.somewebsite.com subfolder of the current working directory (the value of system property user.dir). The name you provide is resolved to a file using the File class.
URL objects are the generic way to solve this. You can use URLs to access local files but also network hosted resources. The URL class supports the file:// protocol besides http:// or https:// so you're good to go.
Pure Java:
urlToInputStream(url,httpHeaders);
With some success I use this method. It handles redirects and one can pass a variable number of HTTP headers asMap<String,String>. It also allows redirects from HTTP to HTTPS.
private InputStream urlToInputStream(URL url, Map<String, String> args) {
HttpURLConnection con = null;
InputStream inputStream = null;
try {
con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(15000);
con.setReadTimeout(15000);
if (args != null) {
for (Entry<String, String> e : args.entrySet()) {
con.setRequestProperty(e.getKey(), e.getValue());
}
}
con.connect();
int responseCode = con.getResponseCode();
/* By default the connection will follow redirects. The following
* block is only entered if the implementation of HttpURLConnection
* does not perform the redirect. The exact behavior depends to
* the actual implementation (e.g. sun.net).
* !!! Attention: This block allows the connection to
* switch protocols (e.g. HTTP to HTTPS), which is <b>not</b>
* default behavior. See: https://stackoverflow.com/questions/1884230
* for more info!!!
*/
if (responseCode < 400 && responseCode > 299) {
String redirectUrl = con.getHeaderField("Location");
try {
URL newUrl = new URL(redirectUrl);
return urlToInputStream(newUrl, args);
} catch (MalformedURLException e) {
URL newUrl = new URL(url.getProtocol() + "://" + url.getHost() + redirectUrl);
return urlToInputStream(newUrl, args);
}
}
/*!!!!!*/
inputStream = con.getInputStream();
return inputStream;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Full example call
private InputStream getInputStreamFromUrl(URL url, String user, String passwd) throws IOException {
String encoded = Base64.getEncoder().encodeToString((user + ":" + passwd).getBytes(StandardCharsets.UTF_8));
Map<String,String> httpHeaders=new Map<>();
httpHeaders.put("Accept", "application/json");
httpHeaders.put("User-Agent", "myApplication");
httpHeaders.put("Authorization", "Basic " + encoded);
return urlToInputStream(url,httpHeaders);
}
Here is a full example which reads the contents of the given web page.
The web page is read from an HTML form. We use standard InputStream classes, but it could be done more easily with JSoup library.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.6</version>
</dependency>
These are the Maven dependencies. We use Apache Commons library to validate URL strings.
package com.zetcode.web;
import com.zetcode.service.WebPageReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet(name = "ReadWebPage", urlPatterns = {"/ReadWebPage"})
public class ReadWebpage extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/plain;charset=UTF-8");
String page = request.getParameter("webpage");
String content = new WebPageReader().setWebPageName(page).getWebPageContent();
ServletOutputStream os = response.getOutputStream();
os.write(content.getBytes(StandardCharsets.UTF_8));
}
}
The ReadWebPage servlet reads the contents of the given web page and sends it back to the client in plain text format. The task of reading the page is delegated to WebPageReader.
package com.zetcode.service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.commons.validator.routines.UrlValidator;
public class WebPageReader {
private String webpage;
private String content;
public WebPageReader setWebPageName(String name) {
webpage = name;
return this;
}
public String getWebPageContent() {
try {
boolean valid = validateUrl(webpage);
if (!valid) {
content = "Invalid URL; use http(s)://www.example.com format";
return content;
}
URL url = new URL(webpage);
try (InputStream is = url.openStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(is, StandardCharsets.UTF_8))) {
content = br.lines().collect(
Collectors.joining(System.lineSeparator()));
}
} catch (IOException ex) {
content = String.format("Cannot read webpage %s", ex);
Logger.getLogger(WebPageReader.class.getName()).log(Level.SEVERE, null, ex);
}
return content;
}
private boolean validateUrl(String webpage) {
UrlValidator urlValidator = new UrlValidator();
return urlValidator.isValid(webpage);
}
}
WebPageReader validates the URL and reads the contents of the web page.
It returns a string containing the HTML code of the page.
<!DOCTYPE html>
<html>
<head>
<title>Home page</title>
<meta charset="UTF-8">
</head>
<body>
<form action="ReadWebPage">
<label for="page">Enter a web page name:</label>
<input type="text" id="page" name="webpage">
<button type="submit">Submit</button>
</form>
</body>
</html>
Finally, this is the home page containing the HTML form.
This is taken from my tutorial about this topic.