So I am supposed to Write a program that reads a URI, for example http://www.cs.unca.edu/csci202, contained on the first input line.
And if an exception is raised by the constructor, the program should print a message giving some information about that problem. And if no exception is raised, the program should print the scheme, host and path of the URI using the appropriate methods of the URI. And if any of these URI properties is missing, it should not be printed. I am supposed to use the scanner to be able to type in the URI and then have it print out the scheme Host Path or error message. So far nothing I have tried has worked. Here is what I have so far:
import java.net.URI;
public class Home04 {
public static void main(String[] args) {
try {
URI uri1 = new URI("");
if (uri1.getScheme() != null) {
System.out.println("Sceme:" + uri1.getScheme() );
}
if (uri1.getHost() !=null){
System.out.println("Host:" + uri1.getHost() );
}
if (uri1.getPath() != null){
System.out.println("Path:" + uri1.getPath() );
}
} catch (Exception e) {
System.out.println("Exception" + e);
}
}
}
Your parsing code is correct.
What you need to do is use below to get input from user
Scanner scanner = new Scanner(System.in);
URI uri1 = new URI(scanner.next());
Related
I'm practicing some command injection via runtime exec in Java. For some reason this code doesn't seem to work, and I've been trying to figure it out for several hours now.
import java.net.*;
class Solution {
public static void main(String args[]) {
// url object
URL url = null;
try {
// create a URL
url = new URL(
"https://google.com;/usr/bin/touch pizza.txt");
// get the ExternalForm
String _ExternalForm = url.toExternalForm();
// display the URL
System.out.println("URL = " + url);
// display the ExternalForm
System.out.println("\nString representation= "
+ _ExternalForm);
Runtime.getRuntime().exec("/bin/bash " + _ExternalForm);
}
// if any error occurs
catch (Exception e) {
// display the error
System.out.println(e);
}
}
}
_ExternalForm is a string and it get concat'd to /bin/bash. I've tried all sorts of injections with semicolons, &, |, etc. Any assistance is appreciated.
Alright so when I try to compile this in java, I get the following error message
error: Class names, 'TokenTest', are only accepted if annotation processing is explicitly requested
1 error
What does this mean and how can I fix it? I've tried numerous things but cant understand what it is referring to. Thanks for your help! Does this mean I need to change the name so it isn't TokenTest?
import java.io.*;
import java.util.*;
class TokenTest {
public static void main (String[] args) {
TokenTest tt = new TokenTest();
tt.dbTest();
}
void dbTest() {
DataInputStream dis = null;
String dbRecord = null;
try {
File f = new File("sales.info");
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
// read the first record of the database
while ( (dbRecord = dis.readLine()) != null) {
StringTokenizer st = new StringTokenizer(dbRecord, ",");
String fname = st.nextToken();
String lname = st.nextToken();
String city = st.nextToken();
String state = st.nextToken();
System.out.println("First Name: " + fname);
System.out.println("Last Name: " + lname);
System.out.println("City: " + city);
System.out.println("State: " + state + "\n");
}
} catch (IOException e) {
// catch io errors from FileInputStream or readLine()
System.out.println("Uh oh, got an IOException error!" + e.getMessage());
} finally {
// if the file opened okay, make sure we close it
if (dis != null) {
try {
dis.close();
} catch (IOException ioe) {
}
}// end if
}// end finally
} // end dbTest
} // end class
From this link about common problems when compiling Java:
Class names, 'HelloWorldApp', are only accepted if annotation processing is explicitly requested
If you receive this error, you forgot to include the .java suffix when compiling the program. Remember, the command is javac HelloWorldApp.java not javac HelloWorldApp.
After fixing the error, you would get a warning about the use of a deprecated method in the following line:
while ((dbRecord = dis.readLine()) != null) {
This is because DataInputStream#readLine is deprecated. See the class Javadoc page to know why it is deprecated and which API to use instead.
If you receive this error, you forgot to include the .java suffix when compiling the program.
I'm a building a basic program to query Target's API with a store ID and Product ID which returns the aisle location. I think I'm using the URL constructor incorrectly, however (I've had trouble with it in the past and still don't fully understand them). Below is the code I have, redacted the API Key for obvious reasons. The URL I create is valid when put into a browser and no exceptions are thrown but at the the end when I print out the contents of the page it is null. What am I missing? Any help is really appreciated!
package productVerf;
import java.net.*;
import java.io.*;
public class Verify {
public static void main(String args[]) {
// first input is store id second input is product id
String productID = args[0];
String storeID = args[1];
String file = "/v2/products/storeLocations?productId=" + productID
+ "&storeId=" + storeID
+ "&storeId=694&key=REDACTED";
URL locQuery;
URLConnection lqConection = null;
try {
locQuery = new URL("http", "api.target.com", file);
lqConection = locQuery.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader response;
String responseString = "";
try {
response = new BufferedReader(new InputStreamReader(
lqConection.getInputStream()));
while (response.readLine() != null) {
responseString += response.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(responseString);
}
}
Maybe you are reading only even lines
you are reading a line twice? (in while statement...), it looks you reads the first line which is dropped in while condition test. If your response contains only one line, nothing will be readed
use this:
String line;
while ((line=response.readLine()) != null) {
responseString += line;
}
I'm having problems with my try-catch exception here. Actually what it does is to prompt the user for the name of a text file say, Robot.txt but if say the file does not exist, I have to make sure that the application reprompts the user for the file name. Hope you guys can understand I'm still a newbie here so please feel free to provide suggestions or advices on my coding etc. Cheers!
Main method class:
import java.io.*;
import java.util.Scanner;
import java.util.Vector;
class TestVector3 {
public static void main(String [] args)
{
System.out.println("Please enter the name of the text file to read: ");
Scanner userInput = new Scanner(System.in);
Vector <KillerRobot> robotDetails = new Vector <KillerRobot>();
KillerRobot robot;
Scanner fileInput = null;
try
{
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
System.out.println("Re-enter file name :"); //Reprompt user for name of the text file
fileInput = new Scanner(userInput.nextLine());
}
while(fileInput.hasNext())
{
robot = new KillerRobot();
String first = fileInput.next();
robot.setName(first);
String second = fileInput.next();
robot.setMainWeapon(second);
int third = fileInput.nextInt();
robot.setNumberOfKills(third);
robotDetails.add(robot);
}
for(KillerRobot i : robotDetails)
{
System.out.println(i);
}
fileInput.close();
}
}
KillerRobot class file:
class KillerRobot {
private String name;
private String mainWeapon;
private int numberOfKills;
KillerRobot()
{
}
public String getName()
{
return name;
}
public String getMainWeapon()
{
return mainWeapon;
}
public int getNumberOfKills()
{
return numberOfKills;
}
public String toString()
{
return name + " used a " + mainWeapon + " to destroy " + numberOfKills + " enemies ";
}
public void setName(String a)
{
name = a;
}
public void setMainWeapon(String b)
{
mainWeapon = b;
}
public void setNumberOfKills(int c)
{
numberOfKills = c;
}
}
As you state that you are a beginner, let us first look at the relevant part of your code, to make sure that we talk about the same thing:
Scanner fileInput = null;
try {
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e) {
System.out.println("Error - file not found!");
System.out.println("Re-enter file name :");
fileInput = new Scanner(userInput.nextLine());
}
You have an input and you want to check this input for a condition and require a new input until this condition is fulfilled. This problem can be solved using a loop like the following:
Scanner fileInput = null;
do {
System.out.println("Enter file name :");
try {
fileInput = new Scanner(new File(userInput.nextLine()));
} catch (FileNotFoundException e) {
System.out.println("Error - file not found!");
}
} while(fileInput == null);
So finally, why does this work? The fileInput variable is set to null and will remain null until the given file is successfully read from standard input because an exception is thrown otherwise what prevents the fileInput variable to be set. This procedure can be repeated endlessly.
On a side note, for performance reasons, it is normally not a good idea to implement control flow that is based on exceptions. It would be better to check for a condition if a file exists via File::exists. However, if you read the file after checking for its existence, it might have been deleted in the meantime which introduces a racing condition.
Answer to your comment: In Java (or almost any programming language), you can inline expressions. This means that instead of calling two methods in two different statements as in
Foo foo = method1();
Bar bar = method2(foo);
you can simply call
Bar bar = method2(method1());
This way, you save yourself some space (what becomes more and more important if your code gets longer) as you do not need the value that you saved in foo at any other place in your code. Similarly, you can inline (which is how this pattern is called) from
File file = new File(userInput.nextLine())
fileInput = new Scanner(file);
into
fileInput = new Scanner(new File(userInput.nextLine()));
as the file variable is only read when creating the Scanner.
Try putting the try-catch in a loop like below:
Scanner fileInput = null;
while (fileInput==null)
{
try
{
System.out.println("Please enter the file name.");
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
}
}
Next you could think of moving the File creation part into separate method, so that the code was cleaner.
Do not fall for try-catch instead add this as your functionality. Exceptions are naturally for run time error handling not for logic building.
Check if file exists at given location.
File textFile = new File(userInput.nextLine());
// Check if file is present and is not a directory
if(!textFile.exists() || textFile.isDirectory()) {
System.out.println("Error - file not found!");
//Reprompt user for name of the text file
System.out.println("Re-enter file name :");
fileInput = new Scanner(userInput.nextLine());
}
You can put while loop instead of if loop if you want to continuously prompt user until correct path is entered.
You can call back your main(), like following
try
{
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
main(args); // recursively call main() method
}
Now if user first attempt wrong then your code will asked to re enter file name.
How to check isFile exist?
File file = new File(filePathString);
if(file.exists() && !file.isDirectory()){
System.out.println("file exist");
}
This really is an XY problem because you assumed the only way to check for a file existence is by catching a FileNotFoundException (hence asking about try-catch exception handling) whereas other means exist to help you avoid a try-catch idiom in an elegant manner.
To check if a file exists at the given path or not you can simply use the File.exists method. Please also see the File.isFile method and/or the File.isDirectory method to verify the nature of the targeted File object.
EDIT : As stated by raphw, this solution is best used in simple scenario since it can incur a race condition in the case of concurrent file deletion happening during the file existence check. See his answer for handling more complex scenario.
I think it's easier to just show the code and the output I'm getting than trying to explain it :)
This is from my main method:
//prompt user for filename
System.out.println("Please enter the text file name. (Example: file.txt):");
String filename = ""; //will be used to hold filename
//loop until user enters valid file name
valid = false;
while(!valid)
{
filename = in.next();
try
{
reader.checkIfValid(filename);
valid = true; //file exists and contains text
}
catch (Exception e)
{
System.out.println(e + "\nPlease try again.");
}
}
And this is the reader.checkIfValid method:
public void checkIfValid(String filename) throws InvalidFileException, FileNotFoundException
{
try
{
in = new Scanner(new File(filename));
if (!in.hasNextLine()) // can't read first line
throw new InvalidFileException("File contains no readable text.");
}
finally
{
in.close();
}
}
This is the output I get when a nonexistent file is entered:
Please enter the text file name. (Example: file.txt):
doesNotExist.txt
java.lang.NullPointerException
Please try again.
Why is the System.out.println(e) getting a NullPointerException? When I enter an empty file or a file with text, it works just fine. The empty file prints the InvalidFileException (a custom exception) message.
When I put a try-catch statement around the "in = new Scanner(new File(filename));", and have the catch block display the exception, I do get the FileNotFoundException printed out, followed by the NullPointerException (I'm not entirely sure why the catch block in the main method would be activated if the exception was already caught in the checkIfValid method...).
I've spent a while on this and I'm completely clueless as to what's wrong. Any help would be appreciated. Thanks!
edited: I think the null pointer comes from the call to reader, it is poor practise to catch all exceptions as you no longer know where they came from!
Maybe the checkIfValid method should just check if the filename is valid?
public boolean checkIfValid(String filename) {
try {
File file = new File(filename);
return file.exists();
} catch (FileNotFoundException) {
System.out.println("Invalid filename ["+filename+"] "+e);
}
}
Then the code calling it could look like;
filename = in.next();
valid = reader.checkIfValid(filename);
if (valid)
List<String> fileContents = readFromFile(filename);
Then contain all the file reading logic in it's own method like this;
public List<String> readFromFile(filename) {
List<String> fileContents = new ArrayList<String>();
try {
in = new Scanner(new File(filename));
while (in.hasNextLine()) {
fileContents.add(in.nextLine);
}
} catch (IOException e){
//do something with the exception
} finally {
in.close();
}
return fileContents;
}
My mistake was something only I could've seen. I was catching all the exceptions so I wasn't able to see where it was coming from. Thank you for helping!