Collage

n. A piece of art made by sticking various different materials, aka PHENOMENA Magazine
Department
John Doe · Feb. 3, 2023, 6:35 a.m.
Sometimes NGINX may show trailing slash in website URLs. Here’s how to remove trailing slash in NGINX to make your URLs look more intuitive.   Remove trailing slash in NGINX Here are the steps to remove trailing slash in NGINX.   1. Open NGINX configuration file Open terminal and run the following command to open NGINX server configuration file. $ sudo vi /etc/nginx/nginx.conf If you have configured separate virtual hosts for your website (e.g www.example.com), such as /etc/nginx/sites-enabled/website.conf then open its configuration with the following command $ sudo vi /etc/nginx/sites-enabled/website.conf 2. Remove trailing slash Add the following rewrite rule in server block as shown in bold. Replace example.com below with your domain name server { listen 80; server_name example.com; rewrite ^/(.*)/$ /$1 permanent; } In the above code, the rewrite statement will redirect all URLs to those without trailing slash. If you want to remove trailing slash from only a specific URL (e.g /product/) then update the rewrite statement as shown below. server { listen 80; server_name mydomain.com; rewrite ^/product/$ /product permanent; }   * You can also use this method. Remove the trailing slash from all paths except mypath. location ~ ^/mypath(.*) { try_files $uri @tomcat; } location ~ (?<no_slash>.*)/$ { return 301 $no_slash; } ... location / { try_files $uri @tomcat; } location @tomcat { ... }   3. Restart NGINX Server Run the following command to check syntax of your updated config file. $ sudo nginx -t If there are no errors, run the following command to restart NGINX server. $ sudo service nginx reload #debian/ubuntu $ systemctl restart nginx #redhat/centos
John Doe · Jan. 29, 2023, 9:54 p.m.
nginx
There are more ideas to the page in this auspicious debut novel than many science fiction novels have in their entirety. In its twenty-second century world the world's survived the mega-terrorism of "the Outrage" that occurred in the 2060s and is now wondrously nanotechnical. Production is unneeded as any product can be extruded from recycled materials. Lifespans extend for hundreds of rejuvenated years. Nanoprocessors residing in one's body link to personal AI "valets" (later "mentars") that amplify one's life a myriad ways. Skilled trades -- like security and nursing -- are filled by an underclass of specialized clones, Robot "arbeitors" perform lowlier tasks. The world is so perfect there are just too many people for it. Jobs are scarce and money, for most, is scarcer. Core character Samson Harger, a packaging artiste, marries fellow "aff" -- "affluents" run the world with a pettiness and ruthlessness akin to medieval royalty -- Eleanor Starke, a high-powered corporate prosecutor who becomes one of the most influential people in the world. Just as they are granted the nearly unheard of privilege to have a child, their marriage is torn apart when Harger is misidentified by Homeland Command as a criminal and consequently "seared." Searing deprives Harger of the now-common (as long as one can afford it) lifespan of hundreds of years. He is left with perhaps four decades of life as a smelly social outcast. The story skips ahead 40 years and Starke, pursuing a colonization project to help relieve the masses, is assassinated in the crash of her space yacht, but daughter Ellen survives -- at least her decapitated head does. Ellen can be rejuvenated -- but only if her head avoids those who want her dead. The back story of Harger's seared life and subplots weaving around the goal of saving Ellen show more of the fascinating aspects of Marusek's dystopia and its denizens. Marusek evokes an impelling sense of wonder with an awesomely imaginative and all-too-believable future chock full of nifty details while allowing his characters to compel the novel. Counting Heads is a marvelous must-read from an author who must be noted as an important new voice in science fiction. -- (in CFQ Jan/Feb 2006 issue)   xwidget_78_Counting Heads
John Doe · Jan. 17, 2023, 6:55 a.m.
xwidget_77_Play Dead   There's a lot of style to Play Dead and some will find a fast-paced, entertaining read. But... Michael Arnzen is a talented, intelligent writer. His flair and potential was first noted with his first novel Grave Markings (1994). Academia intervened and the fiction slowed as he completed graduate degrees and became a college professor. He re-emerged a few years back with poetry and short fiction. A trademark of Arnzen's recent work is its cleverness. With 100 Jolts: Shockingly Short Stories, for example, Arnzen applied the "literary" device of flash fiction exclusively to horror so as to prove his stated point that "[h]orror is the genre of the jolt, the shock, the spark." Each short-short story was intended to elicit an immediate reaction from the reader. It was an interesting experiment. Some of the stories succeed as stories, many of them don't. I applaud the experiment and delight in the ingenuity. It may even stand as a pioneering effort. But, as a story collection, it is not a complete success -- at least by my definition. [In some ways, 100 Jolts is an expression of the 1984 Stephen King statement in Danse Macabre that is usually abbreviated to, "I'll go for the gross-out." A fuller rendition of that quotation is: "I recognize terror as the finest emotion... and so I will try to terrorize the reader. But if I cannot terrify him/her, I will try to horrify; and if I cannot horrify, I'll go for the gross-out. I'm not proud." I wonder if, more than twenty years on, Stephen King still feels this way? I can't speak for King, but, to me, horror is much more than "shock." Nor can I agree with Arnzen's belief (also from his introduction), "Horror stories conflict is always about life and death, but death...always comes as a surprise. The climax of a horror tale is almost unilaterally a killing blow, catching someone or something unaware."] Back to the point -- Arnzen is a clever writer and 100 Jolts is a clever experiment and worth reading, but it is not a great collection. Play Dead, his long-awaited second novel, is also clever, but it is not a great novel. Play Dead's cleverness is displayed in several ways. The most obvious: It's about card playing and is divided into four parts, one for each suite of the deck. It has 52 chapters, each representing a card of the deck. Another example: A character named Axe is a cook. He gets "the axe" at work. A character thinks, "Axe got the axe." A couple of paragraphs later the same character thinks about how he must "bury the hatchet" and make peace. On the next page the character finds Axe in a dumpster and decides he has to bury Axe and thinks: "Had to bury the hatchet. Literally." This is a book in which you know what will happen next if a character says, "You bet your life." And, of course, there is a great deal of wordplay with card and gambling-related terms. The plot revolves around Johnny Frieze, a none-too-bright gambler down on his luck. Johnny sees life as sheer chance and pure luck. A bad guy, Nebo, and his henchman, Winston, are setting up a game of "Butcher Boy" and each of four players must make up a suite of the deck by taking Polaroids that "capture life." This are then turned into cards. Extra points are added for creativity. (I'm sure there is no need to translate what "capturing life" means.) Once the deck is complete the four players are to play to the death with the single survivor walking away with a million bucks (and a lot of bad karma). Why? We are, at first, offered an obvious extolling of cliches by Nebo: "Playing people...Life is a game...Without the possibility of loss there is no game...This is my game...." We later get a possible supernatural tie-in involving "prophecy cards" and the power of capital "F" Fate. Johnny becomes a player and is to provide the spades. Johnny's fellow players are Shorty, Ferret, and Preacher. Like most fictional characters with unfortunate nicknames, these guys are homicidal maniacs and immediately go about "capturing life" with great psychopathological fervor. Johnny, however, tries to cheat fate and Nebo. There are two female characters. Gin is Johnny's love interest and, therefore, endangered. The first paragraph of their first love scene begins: "Her lips tested like warm bread..." and ends "She tasted like a warm worm of menthol scotch." She's a tasty girl. Violet is an old slot machine queen. (We are never sure how old. A hint comes from the end and places her over 65, maybe 70.) Violet reads the Tarot and talks about fate-with-a-small-"f". Violet has some odd quirks for someone who evidently believes in her cards -- like keeping her deck bound with a rubber band and calling card that sure sounds like the Knight of Swords the King of Swords. I'm reviewing from an Advanced Review Copy, so maybe the knight/king will change, but, the point is: for novel in which Tarot plays a role, it seems a bit under-researched. There's a penultimate card game (these cards are well-researched and far more convincing, even if you are not a veteran poker player) and a clever trick ending that may pull the rug out from under the entire book for you. Play Dead lacks the sort of authenticity that is hard to define, but notable when missing. Instead of living, breathing, right-out-of-Vegas characters we get varying degrees of characterizations and no real feel for Vegas's unique reality. Any environment demands a response and Vegas demands a great deal. A better sense of place might also have provided more psychological nuance and more atmosphere. Oh we are told Vegas is "heaven right smack dab in the middle of hell" and that that it offers the tourists "one big excuse to be a loser for a day, and be damned proud of throwing their money away in a perverse ritual as moronic as religious fasting" -- but we feel neither the damnation of the flames nor the artificial salvation of air conditioning. Likewise the living hell of addiction is an underlying metaphor, but the reader is unlikely to feel any of that particular hell either. As I said before the, some readers will find the novel be a fast-paced, entertaining read. Maybe it will be "good" for them. Not all novels are, after all, "great." But this one could have been somewhat greater and shown more than the potential the author is already known to possess. Or, perhaps, Arnzen's talent might have been better served with fresh material. (Play Dead's first incarnation was as his Master's thesis.) Whatever the case, I look forward to his future work. (from Cemetery Dance #53)
John Doe · Jan. 17, 2023, 6:52 a.m.
Touched by Venom is certainly not the first fantasy novel to deal with a headstrong outcast girl and her fascination with dragons, but it is definitely the first in which bestiality is not only a positive, but provides spiritual enlightenment. First of a planned trilogy, this remarkable debut novel prologues with its young heroine witnessing some highborn thugs violently murdering her father and crippling her mother. Nine-year-old Zarq, her father, beautiful older sister, and mother, Kavarria, are members of the pottery clan who live, as do similar serfs, on the estate of a dragonlord. Kavarria, despite belonging to the hated Djimbi race, is valued for her artistry, healing, and helpful spells. She has hopes that her sexually enticing eldest, Waivia, will capture a lusty young noblepis attention and move far up the societal scale. Itpis about the only way a female can better herself in the male-dominated feudal society. All plans go array, however, and Waivia becomes, instead, a lowly sex slave. Kavarria goes to extraordinary lengths to save her, but her heroics result in the violent events of the prologue. Zarq and her insane mother seek refuge first in the macabre Zone of the Dead then in a convent of castrated holy women who care for old bull dragons. Even after death, Kavarria remains a devastating presence in Zarqpis life and in an effort to escape maternal haunting, she turns to the comfort of the highly addictive venom of the dragons. Zarqpis story continues with many grim but fascinating twists as Zarq moves toward her seemingly impossible destiny as a dragonmaster. By the bookpis end, future triumph can be dimly envisioned and it is clear that Janine Cross is a significant new voice in fantasy. Donpit be misled by the totally inappropriate cover of a curvaceous brunette; this isnpit run-of-mill girl-meets-dragon fantasy. (CFQ Vol. 37, Issue #8) xwidget_76_Touched By Venom
John Doe · Jan. 17, 2023, 6:48 a.m.
1. Send a request to the following Alexa API. https://data.alexa.com/data?cli=10&url=phenomena.com 2. The Alexa API will return the following XML response. The Alexa ranking is inside the POPULARITY element, the TEXT attribute. <!-- Need more Alexa data? Find our APIs here: https://aws.amazon.com/marketplace/seller-profile?id=4a9dbf38-88b1-4e87-a459-271154a77d2e --> <ALEXA VER="0.9" URL="phenomena.com/" HOME="0" AID="=" IDN="phenomena.com/"> <SD> <POPULARITY URL="phenomena.com/" TEXT="3713994" SOURCE="panel"/> <REACH RANK="3404850"/> <RANK DELTA="+652325"/> </SD> </ALEXA> 3. We use a DOM parser to directly select the POPULARITY element and print out the value of the TEXT attribute. package com.bad.blood.test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; public class ReadXmlAlexaApi { private static final String ALEXA_API = "http://data.alexa.com/data?cli=10&url="; private final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); public static void main(String[] args) { ReadXmlAlexaApi obj = new ReadXmlAlexaApi(); int alexaRanking = obj.getAlexaRanking("phenomena.com"); System.out.println("Ranking: " + alexaRanking); } public int getAlexaRanking(String domain) { int result = 0; String url = ALEXA_API + domain; try { URLConnection conn = new URL(url).openConnection(); try (InputStream is = conn.getInputStream()) { // unknown XML better turn on this dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); DocumentBuilder dBuilder = dbf.newDocumentBuilder(); Document doc = dBuilder.parse(is); Element element = doc.getDocumentElement(); // find this tag "POPULARITY" NodeList nodeList = element.getElementsByTagName("POPULARITY"); if (nodeList.getLength() > 0) { Element elementAttribute = (Element) nodeList.item(0); String ranking = elementAttribute.getAttribute("TEXT"); if (!"".equals(ranking)) { result = Integer.parseInt(ranking); } } } } catch (Exception e) { e.printStackTrace(); throw new IllegalArgumentException("Invalid request for domain : " + domain); } return result; } } The domain phenomena.com ranked 3713994. Ranking: 3713994 ref. https://mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/
John Doe · Jan. 16, 2023, 8:24 p.m.
XML
1. XML File <book> <person> <first>Kiran</first> <last>Pai</last> <age>22</age> </person> <person> <first>Bill</first> <last>Gates</last> <age>46</age> </person> <person> <first>Steve</first> <last>Jobs</last> <age>40</age> </person> </book> 2. Program Listing import java.io.File; import org.w3c.dom.Document; import org.w3c.dom.*; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; public class ReadAndPrintXMLFile{ public static void main (String argv []){ try { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); Document doc = docBuilder.parse (new File("book.xml")); // normalize text representation doc.getDocumentElement ().normalize (); System.out.println ("Root element of the doc is " + doc.getDocumentElement().getNodeName()); NodeList listOfPersons = doc.getElementsByTagName("person"); int totalPersons = listOfPersons.getLength(); System.out.println("Total no of people : " + totalPersons); for(int s=0; s<listOfPersons.getLength() ; s++){ Node firstPersonNode = listOfPersons.item(s); if(firstPersonNode.getNodeType() == Node.ELEMENT_NODE){ Element firstPersonElement = (Element)firstPersonNode; //------- NodeList firstNameList = firstPersonElement.getElementsByTagName("first"); Element firstNameElement = (Element)firstNameList.item(0); NodeList textFNList = firstNameElement.getChildNodes(); System.out.println("First Name : " + ((Node)textFNList.item(0)).getNodeValue().trim()); //------- NodeList lastNameList = firstPersonElement.getElementsByTagName("last"); Element lastNameElement = (Element)lastNameList.item(0); NodeList textLNList = lastNameElement.getChildNodes(); System.out.println("Last Name : " + ((Node)textLNList.item(0)).getNodeValue().trim()); //---- NodeList ageList = firstPersonElement.getElementsByTagName("age"); Element ageElement = (Element)ageList.item(0); NodeList textAgeList = ageElement.getChildNodes(); System.out.println("Age : " + ((Node)textAgeList.item(0)).getNodeValue().trim()); //------ }//end of if clause }//end of for loop with s var }catch (SAXParseException err) { System.out.println ("** Parsing error" + ", line " + err.getLineNumber () + ", uri " + err.getSystemId ()); System.out.println(" " + err.getMessage ()); }catch (SAXException e) { Exception x = e.getException (); ((x == null) ? e : x).printStackTrace (); }catch (Throwable t) { t.printStackTrace (); } //System.exit (0); }//end of main } 3. Program Output Root element of the doc is book Total no of people : 3 First Name : Kiran Last Name : Pai Age : 22 First Name : Bill Last Name : Gates Age : 46 First Name : Steve Last Name : Jobs Age : 40 https://www.developerfusion.com/code/2064/a-simple-way-to-read-an-xml-file-in-java/
John Doe · Jan. 16, 2023, 8:15 p.m.
XML
package com.bad.blood.test; /* * $Header: /cvsroot/mvnforum/mvnforum/contrib/phpbb2mvnforum/src/org/mvnforum/util/MD5.java,v 1.6 2007/01/15 10:27:31 dungbtm Exp $ * $Author: dungbtm $ * $Revision: 1.6 $ * $Date: 2007/01/15 10:27:31 $ * * * Copyright (C) 2002-2007 by MyVietnam.net * * All copyright notices regarding mvnForum MUST remain * intact in the scripts and in the outputted HTML. * The "powered by" text/logo with a link back to * http://www.mvnForum.com and http://www.MyVietnam.net in * the footer of the pages MUST remain visible when the pages * are viewed on the internet or intranet. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Support can be obtained from support forums at: * http://www.mvnForum.com/mvnforum/index * * Correspondence and Marketing Questions can be sent to: * info at MyVietnam net * * @author: */ import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; // The JavaReference.com Software License, Version 1.0 // Copyright (c) 2002-2005 JavaReference.com. All rights reserved. // // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // 3. The end-user documentation included with the redistribution, if any, must // include the following acknowlegement: // // "This product includes software developed by the Javareference.com // (http://www.javareference.com/)." // // Alternately, this acknowlegement may appear in the software itself, if and // wherever such third-party acknowlegements normally appear. // // 4. The names "JavaReference" and "Javareference.com", must not be used to // endorse or promote products derived from this software without prior written // permission. For written permission, please contact webmaster@javareference.com. // // 5. Products derived from this software may not be called "Javareference" nor may // "Javareference" appear in their names without prior written permission of // Javareference.com. // // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL // JAVAREFERENCE.COM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Software from this site consists of contributions made by various individuals // on behalf of Javareference.com. For more information on Javareference.com, // please see http://www.javareference.com /** * @author anandh */ public class MD5 { static char[] carr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static String getBase64FromHEX(String input) { byte barr[] = new byte[16]; int bcnt = 0; for (int i = 0; i < 32; i += 2) { char c1 = input.charAt(i); char c2 = input.charAt(i + 1); int i1 = intFromChar(c1); int i2 = intFromChar(c2); barr[bcnt] = 0; barr[bcnt] |= (byte) ((i1 & 0x0F) << 4); barr[bcnt] |= (byte) (i2 & 0x0F); bcnt++; } return new String(Base64.getEncoder().encode(barr)); } public static synchronized String getMD5_Base64(String input) { // please note that we dont use digest, because if we // cannot get digest, then the second time we have to call it // again, which will fail again MessageDigest digest = null; try { digest = MessageDigest.getInstance("MD5"); } catch (Exception ex) { ex.printStackTrace(); } if (digest == null) return input; // now everything is ok, go ahead try { digest.update(input.getBytes("UTF-8")); } catch (java.io.UnsupportedEncodingException ex) { ex.printStackTrace(); } byte[] rawData = digest.digest(); return new String(Base64.getEncoder().encode(rawData)); } private static int intFromChar(char c) { char clower = Character.toLowerCase(c); for (int i = 0; i < carr.length; i++) { if (clower == carr[i]) { return i; } } return 0; } public static void main(String[] args) { //String password = args[0]; String password = "phenomena"; MessageDigest digest = null; try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } try { digest.update(password.getBytes("UTF-8")); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); } byte[] rawData = digest.digest(); StringBuffer printable = new StringBuffer(); for (int i = 0; i < rawData.length; i++) { printable.append(carr[((rawData[i] & 0xF0) >> 4)]); printable.append(carr[(rawData[i] & 0x0F)]); } String phpbbPassword = printable.toString(); System.out.println("PHPBB : " + phpbbPassword); System.out.println("MVNFORUM : " + getMD5_Base64(password)); System.out.println("PHPBB->MVNFORUM : " + getBase64FromHEX(phpbbPassword)); } } result: PHPBB : 93625b136e47b789af88d9c766b40064 MVNFORUM : k2JbE25Ht4mviNnHZrQAZA== PHPBB->MVNFORUM : k2JbE25Ht4mviNnHZrQAZA== ref. http://www.java2s.com/Tutorial/Java/0490__Security/GetMD5Base64.htm
John Doe · Jan. 16, 2023, 8:19 a.m.
MD5
package com.bad.blood.test; import java.security.InvalidKeyException; import java.security.Key; import java.util.Base64; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; public class LocalEncrypter { private static String algorithm = "DESede"; private static Key key = null; private static Cipher cipher = null; private static void setUp() throws Exception { key = KeyGenerator.getInstance( algorithm ).generateKey(); cipher = Cipher.getInstance( algorithm ); } public static void main(String [] args) throws Exception { setUp(); byte [] encryptionBytes = null; String input = "phenomena"; System.out.println( "Entered: " + input ); encryptionBytes = encrypt( input ); String encodeString = new String(Base64.getEncoder().encode(encryptionBytes)); System.out.println( "Base64 Encode: " + encodeString ); System.out.println( "Recovered: " + decrypt( Base64.getDecoder().decode(encodeString) ) ); } private static byte [] encrypt(String input) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException { cipher.init( Cipher.ENCRYPT_MODE, key ); byte [] inputBytes = input.getBytes(); return cipher.doFinal(inputBytes); } private static String decrypt(byte [] encryptionBytes) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException { cipher.init( Cipher.DECRYPT_MODE, key ); byte [] recoveredBytes = cipher.doFinal( encryptionBytes ); String recovered = new String( recoveredBytes ); return recovered; } } result: Entered: phenomena Base64 Encode: lfE0CaaNbx1sGUJk6dwgjQ== Recovered: phenomena ref. https://stackoverflow.com/questions/13109588/encoding-as-base64-in-java   * Image to Base64 String Conversion package com.bad.blood.test; import java.io.File; import java.io.IOException; import java.util.Base64; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.Test; import static org.junit.Assert.assertTrue; public class FileToBase64StringConversionUnitTest { private String inputFilePath = "test_image.jpg"; private String outputFilePath = "test_image_copy.jpg"; @Test public void fileToBase64StringConversion() throws IOException { // load file from /src/test/resources ClassLoader classLoader = getClass().getClassLoader(); File inputFile = new File(classLoader .getResource(inputFilePath) .getFile()); byte[] fileContent = FileUtils.readFileToByteArray(inputFile); String encodedString = Base64 .getEncoder() .encodeToString(fileContent); // create output file File outputFile = new File(inputFile .getParentFile() .getAbsolutePath() + File.pathSeparator + outputFilePath); // decode the string and write to file byte[] decodedBytes = Base64 .getDecoder() .decode(encodedString); FileUtils.writeByteArrayToFile(outputFile, decodedBytes); assertTrue(FileUtils.contentEquals(inputFile, outputFile)); } } ref. https://www.baeldung.com/java-base64-image-string
John Doe · Jan. 16, 2023, 8:06 a.m.
base64 encode decode