JSP: Pass Special Characters in response.setHeader? - java

I am getting stuck in a basic JSP Operation. I want to a new line so i have added \n in the end but it throws me an exception. If i remove \n everything works fine
Exception
java.lang.IllegalArgumentException: Invalid LF not followed by whitespace
Class File
StringBuilder junitLog = new StringBuilder();
junitLog.append("The class that is being executed : " + description.getClassName() +"\n");
junitLog.append("Number of testcases to execute : " + description.testCount()+"\n");
/**
* #return the junitLog
*/
public StringBuilder getJunitLog() {
return junitLog;
}
/**
* #param junitLog the junitLog to set
*/
public void setJunitLog(StringBuilder junitLog) {
this.junitLog = junitLog;
}
JSP:-
response.setHeader("finalJUNITReport",""+ junitListener.getJunitLog());

try Base64 encoding them before you set in headers and Base64 decoding them when you want to read them back.

As long as you think to it in the OO way, you can wonder why you couldn't put new line in your headers.
But as soon as you think that it will be transmitted using HTTP protocol, it becomes evident : a HTTP message (request or response) is nothing else than a sequential serie of bytes. For HTTP, the header section comes first and is composed of lines like that :
HEADER_NAME: header value
If you put a new line in a header value, anything that would follow would be considered as a new header. And if you put 2 consecutive new lines that would denote the end of the header section.
All you can do is to use "\n ", because a line beginning with a space if supposed to be a continuation line.
That's the reason of the error message Invalid LF not followed by whitespace, and hopefully it was there, because you would have send an incorrect header section what could be harder to detect ...

I howeva suceeded in my requirement. :)
As clearly stated by Serge Ballesta.
If you put a new line in a header value, anything that would follow would be considered as a new header..
So below is the logic i applied based on my requirement.
Below were my code changes:
junitLog.append("The class that is being executed : " + description.getClassName() +"?");
junitLog.append("Number of testcases to execute : " + description.testCount()+"?");
I added a question mark at the end of the string. THe string became something as mentioned below.
The class that is being executed : testCreateHaulier? Number of testcases to execute : 39?
I passed the String from JSP using response.setHeader Code as below:
response.setHeader("finalJUNITReport",""+ junitListener.getJunitLog());
and in my java class file i did something like this:
junitReportString=yc.getHeaderField("finalJUNITReport").toString();
System.out.println(junitReportString);
junitReportString=junitReportString.replaceAll("\\?", "\n");
System.out.println("Report Details ==============>"+junitReportString);
Using replaceAll i replaced all question marks to new line and my requirement was done.
Hope it helps others too.:)

Related

BYACCJ: How do I include line number in my error message?

This is my current error handling function:
public void yyerror(String error) {
System.err.println("Error: "+ error);
}
This is the default error function I found on the BYACC/J homepage. I can't find any way to add the line number. My question is similar to this question. But the solution to it doesn't work here.
For my lexer I am using a JFlex file.
It's not that different from the bison/flex solution proposed in the question you link. At least, the principle is the same. Only the details differ.
The key fact is that it is the scanner, not the parser, which needs to count lines, because it is the scanner which converts the input text into tokens. The parser knows nothing about the original text; it just receives a sequence of nicely-processed tokens.
So we have to scour the documentation for JFlex to figure out how to get it to track line numbers, and then we find the following in the section on options and declarations:
%line
Turns line counting on. The int member variable yyline contains the number of lines (starting with 0) from the beginning of input to the beginning of the current token.
The JFlex manual doesn't mention that yyline is a private member variable, so in order to get at it from the parser you need to add something like the following to your JFlex file:
%line
{
public int GetLine() { return yyline + 1; }
// ...
}
You can then add a call to GetLine in the error function:
public void yyerror (String error) {
System.err.println ("Error at line " + lexer.GetLine() + ": " + error);
}
That will sometimes produce confusing error messages, because by the time yyerror is called, the parser has already requested the lookahead token, which may be on the line following the error or even separated from the error by several lines of comments. (This problem often shows up when the error is a missing statement terminator.) But it's a good start.

java - How do I print attributes and values of a request object?

I have a request object that probably belons to this class: https://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/connector/RequestFacade.html
I am trying to print the names of the attributes and their values. This is my futile attempt.
Enumeration rns = request.getAttributeNames();
while (rns.hasMoreElements()) {
Object param = rns.nextElement();
out.println("\nattribute name: " + param.toString());
out.println("attribute value: " + request.getAttribute(param.toString()));
}
What I am missing? In another language there is a trivial answer to such question. How different it is done in java?
Rails: How do I print the request parameters?
my hardcoded attempt
Enumeration rns = request.getAttributeNames();
while (rns.hasMoreElements()) {
out.println("\nattribute name: " + rns.nextElement() );
}
// i have copied the logs output from above and edited it to create the array below
String[] madAttrs = { "dayToGraph",
"yearFromGraph",
"yaxis",
"yearToGraph",
"monthToGraph",
"monthFromGraph",
"currentMachine",
"onlyGraph",
"currentSample",
"currentAnalyte",
"dayFromGraph",
"analyteid"};
// then I got what I want.
for (String an : madAttrs) {
out.println("sttribute " + an);
out.println("the value is: "+ request.getAttribute(an));
}
But how do I do it without hardcoding the attributes in the array?
Not the answer you want, but the real answer to your question
Leave the 1990s in the past and stop putting java code in JSP files.
Instead receive the message in a servlet (or Spring handler) and do java work therein.
Next create the display values and put them in some context (perhaps the response) and dispatch the request to your JSP page.
Don't do this
If you refuse to do the above,
import the required classes into your JSP file.
I will not include the syntax for importing files into a JSP file,
but be assured,
Google has fewer compunctions about such things than do I.

Comparing file name to string

I have hit a road block in a program I am writing in Java. The program basically copies folders and files from multiple locations into one folder to make backing up code from multiple locations on my computer easier. The problem I have is that I don't want to copy specific folders, in this case "workspace/.metadata". The start of the code I am having issues with is below:
public void copyFolder(File in, File out, String loc)
throws IOException{
String check = in.getName().substring(1);
System.out.println("loc:"+loc+"check: "+check);
if(loc.equals("java")){
if(check.equals("metadata")){
System.out.println("failboat");
//statusBox.append("failboat");
}
}
And this is the result I see:
loc:java
check: orkspace2
loc:java
check: metadata
loc:java
check: lock
I've had other's look at the code and they agree it should work. I've even created a replica of the code in a test file:
String test = "fmetadata";
String loc = "java";
String check = test.substring(1);
if(loc.equals("java")){
if(check.equals("metadata")){
System.out.print("failboat");
}else{
System.out.println("WTF");
System.out.print(test+ ": :"+check);
}
}
And the result?
failboat
There is a dent in my desk the size of my forehead from trying to figure this out.
If that output you posted is the actual output:
loc:java
check: orkspace2
loc:java
check: metadata
loc:java
check: lock
It does not match the code you've pasted, as you do not print a newline between the two items:
System.out.println("loc:"+loc+"check: "+check);
If this is truly what you are seeing with that code then I would say the problem is that loc has a stray newline at the end, and is actually "java\n" rather than "java" as you expect. So you should go back and examine how you generate the value you pass through loc to begin with before calling that function.
If this is the case, some suggestions for diagnostics improvements that could help you notice these kinds of issues sooner (in addition to stepping through with a debugger):
// quote your strings to spot whitespace, print length to spot unexpected
// unprintable characters.
System.out.println("loc: \""+loc+"\" "+loc.length());
System.out.println("check: \""+check+"\" "+check.length());
And:
if(loc.equals("java")){
// make sure you're getting to this point, don't assume that the first
// if condition was satisfied:
System.out.println("grumpycat"); // <----
if(check.equals("metadata")){
System.out.println("failboat");
}
}

Java - SecurityException in Method "printDuplicates"

I'm a newcomer to Java trying to submit a working project, in this instance printDuplicates. The instructions are as follows:
Write a method named printDuplicates that accepts as its parameter a Scanner for an input file containing a series of lines. Your method should examine each line looking for consecutive occurrences of the same token on the same line and print each duplicated token along how many times it appears consecutively. Non-repeated tokens are not printed. Repetition across multiple lines (such as if a line ends with a given token and the next line starts with the same token) is not considered in this problem.
For example, if the input file contains the following text:
hello how how are you you you you
I I I am Jack's Jack's smirking smirking smirking smirking smirking revenge
bow wow wow yippee yippee yo yippee yippee yay yay yay
one fish two fish red fish blue fish
It's the Muppet Show, wakka wakka wakka
Your method would produce the following output for the preceding input file:
how*2 you*4
I*3 Jack's*2 smirking*5
wow*2 yippee*2 yippee*2 yay*3
wakka*3
Your code prints only the repeated tokens; the ones that only appear once in a row are not shown. Your code should place a single space between each reported duplicate token and should respect the line breaks in the original file. This is why a blank line appears in the expected output, corresponding to the fourth line of the file that did not contain any consecutively duplicated tokens. You may assume that each line of the file contains at least 1 token of input.
Here is my code, pretty much ready for submitting.
import java.io.*;
import java.util.*;
Scanner input;
public static void printDuplicates(Scanner input) throws Exception {
String word = "";
String word2 = "";
input = new Scanner(new File("idontknowwhattodo.txt"));
while(input.hasNextLine()) {
Scanner line = new Scanner(input.nextLine());
int repeat = 1;
word = line.next();
while(line.hasNext()) {
word2 = line.next();
while(word.equals(word2)) {
repeat++;
if(line.hasNext()){
word2 = line.next();
} else {
break;
}
}
if(repeat!=1) {
System.out.print(word + "*" + repeat + " ");
}
repeat = 1;
word = word2;
}
System.out.println();
}
}
However, whenever I try to submit my project, it throws back this error:
(no output was produced!)
SecurityException on line 5:
You are not allowed to read the file /usr/share/tomcat7/temp/idontknowwhattodo.txt
java.lang.SecurityException: You are not allowed to read the file /usr/share/tomcat7/temp/idontknowwhattodo.txt
at java.io.FileInputStream.<init>(FileInputStream.java:135)
at java.io.FileReader.<init>(FileReader.java:72)
at Scanner.<init>(Scanner.java:330)
at printDuplicates (Line 5)
What does this mean? I have multiple working projects but I can't seem to submit them due to this one error. Any experts that can help me on this one? Thank you.
It looks like you are using Tomcat from your path. Tomcat requires special security permission to read or write files. This is a basic protection to prevent malicious code from accessing sensitive files on the OS. You can configure these directories or stick to reading and writing to the default ones:
https://tomcat.apache.org/tomcat-7.0-doc/security-manager-howto.html
Unable to add a comment because of reputation points so using the Answers section.
Agree with above comments, it is related to permissions.
Do an ls -ltr on /usr/share/tomcat7/temp/idontknowwhattodo.txt
Check whether the user (say myuser) with which you are running you java application has necessary permissions for /usr/share/tomcat7/temp/idontknowwhattodo.txt.
Two options below:
Give the user "myuser" the necessary permissions to the idontknowwhattodo.txt using chmod.
Or copy idontknowwhattodo.txt to a location where "myuser" has the permissions.
Problem description says that you're getting Scanner object as parameter. You don't have to recreate it, you're probably trying to submit your project to some online competition. Program on the server will load your class and call the method printDuplicates() with Scanner object as parameter, you don't have to worry about how it gets created. Just use it, and everything would be fine.
Just comment the scanner assignment line as below
String word = "";
String word2 = "";
/*input = new Scanner(new File("idontknowwhattodo.txt"));*/
while(input.hasNextLine()) {
...
As per instructions, you are already getting the Scanner object(which references the input file) as parameter to your method. So, you should not be re-initializing it.
This line should be removed:
input = new Scanner(new File("idontknowwhattodo.txt"));

NumberFormatException error (parseInt)

Hopefully a very simple query, but it's left me scratching my head.
I have a string, which is just a single integer, and I'm trying to then get that integer out as an int. This on the face of it shouldn't be a problem.
// this is how I create the string (it's the playload from a UDP datagram packet,
// thought I don't think the origins hugely important - it's juts a test run so the
// stringMessage is always 1 (created by a seperate client process)
...
recvSoc.receive(pac);
String stringMessage = new String(pac.getData());
port = pac.getPort();
System.out.println("RECEIVED: " + stringMessage + " on port: " + port);
processMessage(stringMessage);
...
// Then in processMessage
public void processMessage(String data) {
int message;
message = Integer.parseInt(data);
...
This always crashes with a NumberFormatException error. I cannot for the life of me figure out what's causing this, any ideas greatly appreciated. I haven't coded much in Java (recently) so might simply be forgetting something critical or what not.
Exception in thread "main" java.lang.NumberFormatException: For input string: "1"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:481)
at java.lang.Integer.parseInt(Integer.java:514)
at udp.UDPServer.processMessage(UDPServer.java:85)
at udp.UDPServer.run(UDPServer.java:52)
at udp.UDPServer.main(UDPServer.java:156)
If the string is really 1, the exception can't happen. So I would say the string is not actually 1.
do a data.toCharArray() and print each character's code (cast to int). It may turn out that there is a hidden character before the digit, for example. (edit: it appears iluxa mentioned this option in a comment while I was writing the answer)
Try data = data.trim() before passing it to parseInt(..)
Note that DatagramPackate.getData() returns the whole buffer!
The data you received is only a part of it:
The data received or the data to be sent starts from the offset in the buffer, and runs for length long.
So to convert the data to a String you should use this constructor:
String message = new String(pac.getData(), pac.getOffset(), pac.getLength(), "UTF-8");
Note that I specify the UTF-8 encoding here, as not specifying an encoding would result in the platform default encoding to be used, which is generally not what you want.

Categories

Resources