The current approach is creating HTML in a ServletTest, run the test, change the Servlet until the test turns into green. However, it feels like that this approach to TDD in Servlets is devious and more time-consuming than TDD ordinary Java classes as HTML created in the ServletTest is copied to the Servlet for the most part and subsequently changed regarding the format (e.g. removing backslashes) instead of testing the output in a Test for ordinary Java Classes and writing most of the code in the main.
ServletTest:
HttpServletRequest mockedHttpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse mockedHttpServletResponse = mock(HttpServletResponse.class);
HttpSession mockedHttpSession = mock(HttpSession.class);
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
private final String doGetHtmlStringPartOne = "<html><body><table>"
+ "<tr><td><h1>";
private final String doGetHtmlStringPartTwo = "<\\/h1><\\/td>"
+ "<form method=\"post\">"
+ "<input type=\"hidden\" name=\"randomDigitRange\" value=\"1\" \\/>"
+ "<input type=\"hidden\" name=\"randomMathematicalOperator\""
+ " value=\"1\" \\/><input type=\"hidden\" name=\"fractionBoolean\""
+ " value=\"";
private final String doGetHtmlStringPartThree = "<td><input type=\"radio\" name=\"userInput\" value=\"(\\d)+.(\\d)+\">(\\d)+(\\s\\/\\s(\\d)+)?<\\/td>";
private final String doGetHtmlStringPartFour = "<\\/tr><tr><td>"
+ "<input type=\"submit\" value=\"Submit\" "
+ "onclick='this.form.action=\"ToBeDefinedServlet\";' \\/>"
+ "<\\/td><\\/tr><\\/table><\\/form><\\/body><\\/html>"
+ "<form action=\"\\/tobedefinedservlet\">"
+ "<input type=\"submit\" value=\"Home\"><\\/form>";
#Test
public void testBooleanFractionTrue() throws IOException, ServletException {
mockDoGet();
assertTrue(stringWriter.getBuffer().toString().trim().matches(expectedDoGetHtmlString("1 \\/ 1 \\+ 1 \\/ 1", true)));
}
public String expectedDoGetHtmlString(String assignment,
Boolean fractionBoolean) {
return doGetHtmlStringPartOne + assignment + doGetHtmlStringPartTwo
+ "" + fractionBoolean + "" + "\" \\/>" + "\\n"
+ doGetHtmlStringPartThree + "\\n" + doGetHtmlStringPartFour;
}
public void mockDoGet() throws IOException, ServletException {
when(mockedHttpServletRequest.getSession()).thenReturn(
mockedHttpSession);
when(mockedHttpServletResponse.getWriter()).thenReturn(printWriter);
when(mockedHttpServletRequest.getParameter("fractionBoolean"))
.thenReturn("true");
when(mockedHttpServletRequest.getParameter("randomDigitRange"))
.thenReturn("1");
when(
mockedHttpServletRequest
.getParameter("randomMathematicalOperator"))
.thenReturn("1");
when(mockedHttpServletRequest.getSession()).thenReturn(
mockedHttpSession);
new ToBeDefinedServlet().doGet(mockedHttpServletRequest,
mockedHttpServletResponse);
}
Servlet:
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
calculation.setFractionBoolean(Boolean.parseBoolean(request
.getParameter("fractionBoolean")));
calculation.setAssignment(Double.parseDouble(request
.getParameter("randomDigitRange")), Double.parseDouble(request
.getParameter("randomMathematicalOperator")));
PrintWriter out = response.getWriter();
out.println("<html><body><table>"
+ "<tr><td><h1>"
+ calculation.getAssignment()
+ "</h1></td>"
+ "<form method=\"post\">"
+ "<input type=\"hidden\" name=\"randomDigitRange\" value=\""
+ request.getParameter("randomDigitRange")
+ "\" />"
+ "<input type=\"hidden\" name=\"randomMathematicalOperator\" value=\""
+ request.getParameter("randomMathematicalOperator") + "\" />"
+ "<input type=\"hidden\" name=\"fractionBoolean\" value=\""
+ request.getParameter("fractionBoolean") + "\" />");
for (double possibleAnswer : calculation.getPossibleAnswersArray()) {
String possibleAnswerFormat = Boolean.parseBoolean(request
.getParameter("fractionBoolean")) == true ? ""
+ new Fraction(possibleAnswer) + "" : "" + possibleAnswer
+ "";
out.println("<td><input type=\"radio\" name=\"userInput\" value=\""
+ possibleAnswer + "\">" + possibleAnswerFormat + "</td>");
}
out.println("</tr>"
+ "<tr><td><input type=\"submit\" value=\"Submit\" "
+ "onclick='this.form.action=\"ToBeDefinedServlet\";' /></td>"
+ "</tr></table></form></body></html>"
+ "<form action=\"/tobedefinedservlet\"><input type=\"submit\" value=\"Home\"></form>");
}
I think the main problem here is that you are building your html page by manually putting the html elements together from various strings. As you have experienced, this leads to code that is hard to test and maintain.
Try using JSF or some simliar technique instead. This will enable you to focus only on the functionality on the Java side, which is much easier to test.
Related
I'm trying to convert html string with Japanese character to PDF using YaHP Html to Pdf Converter.
I am using Eclipse Photon Release (4.8.0)
Here is my main class that invokes the YaHP Html :
public static void main(String[] args) {
String pdfOutFileName = "C:\\test\\JP-Test.pdf";
double pageHeight = 80;
String htmlContent = "<html>\r\n" +
" <head>\r\n" +
" <meta http-equiv=Content-Type content=\"text/html; charset=UTF-8\">\r\n" +
" <style type=\"text/css\">\r\n" +
" span.cls_005hr{font-family:Arial,serif;font-size:16.8px;color:rgb(50,50,50);font-weight:normal;font-style:normal;text-decoration: none}\r\n" +
" div.cls_005hr{font-family:Arial,serif;font-size:14.8px;color:rgb(50,50,50);font-weight:normal;font-style:normal;text-decoration: none}\r\n" +
" </style>\r\n" +
" </head>\r\n" +
" <body>\r\n" +
" <table border=0 cellpadding=0 cellspacing=0 width=720>\r\n" +
" <col width=10 >\r\n" +
" <col width=710 >\r\n" +
" <tr>\r\n" +
" <td valign=\"middle\" height=\"80\" bgcolor=\"#f0f0f0\">\r\n" +
" <div><span class=\"cls_005hr\">JPTesting</span></div>\r\n" +
" </td>\r\n" +
" <td valign=\"middle\" height=\"80\" bgcolor=\"#f0f0f0\">\r\n" +
" <div><span class=\"cls_005hr\">株式会社 ビー・エス・デーインフォメーションテクノロジー</span></div>\r\n" +
" </td>\r\n" +
" </span>\r\n" +
" </tr>\r\n" +
" </table>\r\n" +
" </body>\r\n" +
"</html>";
System.out.println("htmlContent: [" + htmlContent + "]");
try {
ByteArrayOutputStream outFormPDF = new ByteArrayOutputStream();
outFormPDF = PDFUtil.convertHtmlToPDF(htmlContent, pageHeight);
byte[] bOutFormPDF = outFormPDF.toByteArray();
OutputStream os = new FileOutputStream(pdfOutFileName);
os.write(bOutFormPDF);
System.out.println("Successfully Finished writing PDF to output file");
os.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
and here is the PDFUtil class method that calls YaHP Converter
public static ByteArrayOutputStream convertHtmlToPDF (String htmlContent, double pageHeight) throws CConvertException, IOException {
ByteArrayOutputStream outFormPDF = new ByteArrayOutputStream();
Scanner scanner = new Scanner(htmlContent).useDelimiter("\\Z");
String htmlContents = scanner.next();
CYaHPConverter converter = new CYaHPConverter();
Map properties = new HashMap();
List headerFooterList = new ArrayList();
URL resource = PDFUtil.class.getClassLoader().getResource("fonts");
String fontDirectory = resource.getPath() ;
properties.put(IHtmlToPdfTransformer.PDF_RENDERER_CLASS, IHtmlToPdfTransformer.FLYINGSAUCER_PDF_RENDERER);
properties.put(IHtmlToPdfTransformer.FOP_TTF_FONT_PATH, fontDirectory);
PageSize pageSize = IHtmlToPdfTransformer.LEGALP;
if (pageHeight>0) {
String sHeight = Double.toString(pageHeight);
sHeight = sHeight.substring(0,sHeight.indexOf("."));
pageHeight = Double.parseDouble(sHeight);
System.out.println ("pageHeight : " + pageHeight);
pageSize = new PageSize(21.6d, pageHeight, 0.7d, 0.5d, 1.5d, 1.5d);
}
System.out.println ("Calling converter.convertToPdf");
converter.convertToPdf(htmlContents,
pageSize,
headerFooterList,
"file://tmp/Html2PdfConvertTemp",
outFormPDF,
properties);
System.out.println ("Successfully Called converter.convertToPdf");
scanner.close();
return outFormPDF;
}
For some reason, the output PDF file contains "JPTesting", but does not contain the Japanese letters : "株式会社 ビー・エス・デーインフォメーションテクノロジー" .
Any help would be much appreciated.
Found the solution. Posting my solution here in case anyone else may struggle with the same issue that I had.
I have added Japanese font from google : https://fonts.google.com/?subset=japanese (I Picked Shippori Mincho B1), added to my font resource directory.
Updated my html CSS to pick up those new fonts :
span.cls_005jp{font-family:Shippori Mincho B1, Arial,serif;...
Update my html to use those new fonts for tags that may contain Japanese letters :
株式会社 ビー・エス・デーインフォメーションテクノロジー\r\n"
Thank you, #g00se, for pointing me to the right direction!
i developed android app and i used HTML code to Print the result in formatted form.
the code will be like this :
String adress = editText1.getText().toString();
String phone = editText2.getText().toString();
String licenseNo = editText3.getText().toString();
"\n" +
" <div class=\"down\">\n" +
" <div class=\"EASY\">\n" +
" <img src=\"" + image + "\" alt=\"QR\" >\n" +
" </div>\n" +
" <table class=\" info_table\">\n" +
" <tbody>\n" +
" <tr>\n" +
" <td class=\"info\">" + phone + "</td>\n" +
" <td class=\"info\"> " + licenseNo + "</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td class=\"info_A\" colspan=\"2\"> " + adress + "</td>\n" +
" </tr>\n" +
" </tbody>\n" +
" </table>\n" +
" </div>";
as you see it should contain \n and + because its inside a string object contained variable values from user input.
i faced some difficulty when i need to Edit this Piece of code cose i will test it inside the application.
my question is what is the best way to get this code to edit and preview it outside android studio and reinsert it again.
i used find and replace but it make some problems.
hope i explained enough
You can create a XML file in the resources folder, read it and then use format in order to change the values there.
I need to POST data and at the same time redirect to that URL in REST environment. I can do this for normal strings, but the requirement is to POST specific Object.
The way I do it for normal string is -
public Response homePage(#FormParam("username") String username,
#FormParam("passwordhash") String password) {
return Response.ok(PreparePOSTForm(username)).build();
}
private static String PreparePOSTForm(String username)
{
//Set a name for the form
String formID = "PostForm";
String url = "home";
//Build the form using the specified data to be posted.
StringBuilder strForm = new StringBuilder();
strForm.append("<form id=\"" + formID + "\" name=\"" +
formID + "\" action=\"" + url +
"\" method=\"POST\">");
strForm.append("<input type=\"hidden\" name=\"" + "username" +
"\" value=\"" + username + "\">");
strForm.append("</form>");
//Build the JavaScript which will do the Posting operation.
StringBuilder strScript = new StringBuilder();
strScript.append("<script language=\"javascript\">");
strScript.append("var v" + formID + " = document." +
formID + ";");
strScript.append("v" + formID + ".submit();");
strScript.append("</script>");
//Return the form and the script concatenated.
//(The order is important, Form then JavaScript)
return strForm.toString() + strScript.toString();
}
But this method is not sending Objects. I need a work around to send complex Objects. Please help me with this issue.
Thanks in advance.
I am working on Java RestFul WebProjects. In my Project I have one util package that uses JavaMail.java class. In this project I am sending mails to our requirement for that purpose I am adding HTML tags at my String body variable and passing my html code.
My doubt is i need to place html code at one file in my localhost and I need to give the html file path to that string body variable. Is it possible and can anybody help me?
Here i am placing my JavaMail.Java class code:
public static void sendEmailForProfileActivation(int activationCode, String to) throws AddressException, MessagingException {
/**
* Sender's credentials
* */
String from = "helloworld#gmail.com";
String password = "888888";
String sub = "Activate Your Profile using activation code";
//String body = "Activate Profile Using the active Code: <b>" + activationCode + "</b>.";
String body="<html>"
+ "<body>"
+ "<table width=\"100%"+"\" cellpadding=\"0"+"\" cellspacing=\"0"+"\" bgcolor=\"e4e4e4"+"\">"
+ "<tr>"
+ "<td>"
+ "<table id=\"top-message"+"\" cellpadding=\"20"+"\" cellspacing=\"0"+"\" width=\"600"+"\" align=\"center"+"\">"
+ "<tr>"
+ "<td align=\"center"+"\">"
+ "<p>Trouble viewing this email? View in Browser</p>"
+ "</td>"
+ "</tr>"
+ "</table><!-- top message -->"
+ "<table id=\"main"+"\" width=\"570"+"\" align=\"center"+"\" cellpadding=\"0"+"\" cellspacing=\"15"+"\" bgcolor=\"ffffff"+"\">"
+ "<tr>"
+ "<td>"
+ "<table id=\"header"+"\" cellpadding=\"10"+"\" cellspacing=\"0"+"\" align=\"center"+"\" bgcolor=\"8fb3e9"+"\">"
+ "<tr>"
+ "<td width=\"570"+"\" bgcolor=\"#7EB646"+"\">"
+ "<h1><font color=\"white"+"\">HelloWorld Services 15 July 2015</font></h1>"
+ "</td>"
+ "</tr>"
+ "<tr>"
+ "</tr>"
+ "</table><!-- header -->"
+ "</td>"
+ "</tr><!-- header -->"
+ " <!--tr>"
+ "<td height=\"30"+"\">"
+ "<img src=\"http://dummyimage.com/570x30/fff/fff"+"\" />"
+ "</td>"
+ "</tr For spacing pupose one image to another where you want space you add this image-->"
+ "<tr>"
+ "<td>"
+ "<table id=\"content-6"+"\" cellpadding=\"0"+"\" cellspacing=\"0"+"\" align=\"center"+"\">"
+ "<p align=\"center"+"\">Activate Profile Using the active Code: <b>" + activationCode + "</b>.</p>"
+ "<p align=\"center"+"\">Activate Your Account</p>"
+ "</table>"
+ "</td>"
+ "</tr>"
+ "</table><!-- main -->"
+ "<table id=\"bottom-message"+"\" cellpadding=\"20"+"\" cellspacing=\"0"+"\" width=\"600"+"\" align=\"center"+"\">"
+ "<tr>"
+ "<td align=\"center"+"\">"
+ "<p>You are receiving this email because you signed up for updates</p>"
+ "<p>Unsubscribe instantly | Forward to a friend | View in Browser</p>"
+ "<p> <img src=\"file:///home/yavat6/Downloads/manDoctor.png"+"\" style=\"width:50px;float:left;height:35px;"+"\"/>If you have any queries contact to us via mail 24*7CONTACT US</p>"
+ "</td>"
+ "</tr>"
+ "</table><!-- bottom message -->"
+ "</table><!-- 100% -->"
+ "</body>"
+ "</html>";
sendMessage(from, password, to,sub, body);
}
Yes you can send the HTML file in your java code. You can make use of getResourceAsStream() to read your .html file and then get the content of this .html file in a String and send this content as a message like :-
InputStream is = Sum.class.getClassLoader().getResourceAsStream("test.html"); // read file as stream, add this html file in yur class path.
BufferedReader br = new BufferedReader(new InputStreamReader(is)) ;
StringBuilder sb = new StringBuilder();
String str = null;
while((str=br.readLine()) != null)
sb.append(str);
String send_to = "test#gmail.com"; // add sender here
Message msg = new MimeMessage(mailSession);
try{
msg.setSubject("Test Email");
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(send_to, false));
String message = sb.toString(); // your html message as string
msg.setContent(message, "text/html; charset=utf-8");
msg.setSentDate(new Date());
Transport.send(msg);
}catch(MessagingException me){
// catch exception here
}
I have created an html string in which I need to set the background image.
protected void onPostExecute(HashMap<String,String> hPlaceDetails){
String backgroundImage = ??????
String name = hPlaceDetails.get("name");
String icon = hPlaceDetails.get("icon");
String vicinity = hPlaceDetails.get("vicinity");
String lat = hPlaceDetails.get("lat");
String lng = hPlaceDetails.get("lng");
String formatted_address = hPlaceDetails.get("formatted_address");
String formatted_phone = hPlaceDetails.get("formatted_phone");
String website = hPlaceDetails.get("website");
String rating = hPlaceDetails.get("rating");
String international_phone_number = hPlaceDetails.get("international_phone_number");
String url = hPlaceDetails.get("url");
String mimeType = "text/html";
String encoding = "utf-8";
String data = "<html>"+
"<body background="+backgroundImage+"><img style='float:left' src="+icon+" /><h1><center>"+name+"</center></h1>" +
"<br style='clear:both' />" +
"<hr />"+
"<p>Vicinity : " + vicinity + "</p>" +
"<p>Location : " + lat + "," + lng + "</p>" +
"<p>Address : " + formatted_address + "</p>" +
"<p>Phone : " + formatted_phone + "</p>" +
"<p>Website : " + website + "</p>" +
"<p>Rating : " + rating + "</p>" +
"<p>International Phone : " + international_phone_number + "</p>" +
"<p>URL : <a href='" + url + "'>" + url + "</p>" +
"</body></html>";
// Setting the data in WebView
mWvPlaceDetails.loadDataWithBaseURL("", data, mimeType, encoding, "");
}
Note: I have my background image (background9.png) in the location MyProject/res/drawable-xhdpi. Please suggest how I need to set
<body background="+backgroundImage+">
Instead of using \res\drawable-xhdp\background9.png as the path as you mentioned in your comment, you should use:
<body background='file:///android_res/drawable/background9.png'>
I've just tested this and it works perfectly.
Please add a tag for android to clarify your question.
Anyway, you need to get a reference for your parent layout, by using findViewById(R.id.yourActivitysParentLayout)
You need then to set it's background using a ResourceManager. From the top of my head, the method name you will need is yourparent.setBackgroungDrawable(drawable). The drawable can be obtained from a resource manager instance.
This can all be avoided by setting it's background in the xml if possible by using android:background="#drawable/background9" //sorry not sure if .png is needed. xhdp is not though.