I'm creating an application that uses web view to load the website and allow to download data like IMG/PDF/GIF. The problem is that the download link is not a normal link it's blob:.
I know blob: URL does not refer to the data that exists on the server, it refers to data that your browser currently has in memory.
class DownloadBlobFileJSInterface {
private Context mContext;
private DownloadGifSuccessListener mDownloadGifSuccessListener;
public DownloadBlobFileJSInterface(Context context) {
this.mContext = context;
}
public static String getBase64StringFromBlobUrl(String blobUrl) {
if (blobUrl.startsWith("blob")) {
return "javascript: var xhr = new XMLHttpRequest();" +
"xhr.open('GET', '" + blobUrl + "', true);" +
"xhr.setRequestHeader('Content-type','image/gif');" +
"xhr.responseType = 'blob';" +
"xhr.onload = function(e) {" +
" if (this.status == 200) {" +
" var blobFile = this.response;" +
" var reader = new FileReader();" +
" reader.readAsDataURL(blobFile);" +
" reader.onloadend = function() {" +
" base64data = reader.result;" +
" Android.getBase64FromBlobData(base64data);" +
" }" +
" }" +
"};" +
"xhr.send();";
}
return "javascript: console.log('It is not a Blob URL');";
}
public void setDownloadGifSuccessListener(DownloadGifSuccessListener listener) {
mDownloadGifSuccessListener = listener;
}
#JavascriptInterface
public void getBase64FromBlobData(String base64Data) {
convertToGifAndProcess(base64Data);
}
private void convertToGifAndProcess(String base64) {
ContextWrapper wrapper = new ContextWrapper(mContext);
String fullPath =wrapper.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString();
File gifFile = new File(fullPath+ "/File_" + System.currentTimeMillis() + "_.gif");
saveGifToPath(base64, gifFile);
Toast.makeText(mContext, "Downloaded", Toast.LENGTH_SHORT).show();
if (mDownloadGifSuccessListener != null) {
mDownloadGifSuccessListener.downloadGifSuccess(gifFile.getAbsolutePath());
}
}
private void saveGifToPath(String base64, File gifFilePath) {
try {
byte[] fileBytes = Base64.decode(base64.replaceFirst(
"data:image/gif;base64,", ""), 0);
FileOutputStream os = new FileOutputStream(gifFilePath, false);
os.write(fileBytes);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public interface DownloadGifSuccessListener {
void downloadGifSuccess(String absolutePath);
}
}
I want to download the file in device storage.
Is there any way to get data from the blob: URL?
Or
Is it possible to send that data to chrome to download.
I know there is a lot of questions out there like this, this on StackOverflow, I almost tried all but didn't find any of these working.
Related
I have wsdl service. All request and response saving in minio bucket. But when content too big, in minio saved only part of this content.
My Interceptor
#Slf4j
#Component
public class LogResponseInterceptor extends AbstractPhaseInterceptor<Message> {
private final MinioService minioService;
private final AdministrationWebClient administrationWebClient;
public LogResponseInterceptor(MinioService minioService, AdministrationWebClient administrationWebClient) {
super(Phase.PRE_PROTOCOL_ENDING);
this.minioService = minioService;
this.administrationWebClient = administrationWebClient;
}
#Override
public void handleMessage(Message message) throws Fault {
try (CachedOutputStream outputStream = ((CachedOutputStream) message.getContent(OutputStream.class));
InputStream inputStream = outputStream.getInputStream()) {
UUID uuid = UUID.randomUUID();
minioService.uploadFile(
inputStream, Constantas.MinioConst.MINIO_SPV_OUT_PATH, uuid.toString(), "application/xml"
);
SpvRecord spvRecord = SpvRequestContext.getSpvRequest();
spvRecord.setRequestState(RequestState.COMPLETED);
spvRecord.setResponseXmlUrl(Constantas.MinioConst.MINIO_SPV_OUT_PATH + uuid);
spvRecord.setFinishDate(ZonedDateTime.now());
log.info("End spv action with {}", spvRecord);
spvRecord.setRequestNumber(administrationWebClient.getSpvLastRequestNumber() + 1);
administrationWebClient.createSpvRecord(spvRecord);
} catch (IOException e) {
log.error("### Error while get response xml");
throw new RuntimeException(e);
} finally {
SpvRequestContext.clear();
}
}
}
CachedOutputStream contains only part of response body. How i can get full response body?
You can try lowering the level of the phase.The attachment interceptor is at the receive level (version 3.3.7).
To get the request you can try this, copy the original content to be able to flush it.
// now get the request xml
InputStream is = message.getContent ( InputStream.class );
CachedOutputStream os = new CachedOutputStream ( );
IOUtils.copy ( is, os );
os.flush ( );
message.setContent ( InputStream.class, os.getInputStream ( ) );
is.close ( );
System.out.println ("The request is: " + IOUtils.toString ( os.getInputStream ( ) ));
os.close ( );
To get the response, you need made custom implementation del original
https://github.com/apache/cxf/blob/main/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java
and modify the method onClose(CachedOutputStream cos) with this
public void onClose(CachedOutputStream cos) {
final LogEvent event = eventMapper.map(message);
if (shouldLogContent(event)) {
copyPayload(cos, event);
} else {
event.setPayload(CONTENT_SUPPRESSED);
}
StringBuilder sb = new StringBuilder("\nOutbound Message\n---------------------------\n");
sb.append("ID: " + event.getExchangeId() + " \n");
sb.append("Address: " + event.getAddress() + " \n");
sb.append("Encoding: " + event.getEncoding() + " \n");
sb.append("Content-Type: " + event.getContentType() + " \n");
sb.append("Headers: " + event.getHeaders() + " \n");
if(event.isTruncated()) {
sb.append("Payload (truncated) : " + event.getPayload() + " \n");
} else {
sb.append("Payload: " + event.getPayload() + " \n");
}
sb.append("---------------------------");
this.logger.trace(sb.toString());
try {
// empty out the cache
cos.lockOutputStream();
cos.resetOut(null, false);
} catch (Exception ex) {
// ignore
}
message.setContent(OutputStream.class, origStream);
}
IMPORTANT: the limit truncate the response, set limit to max for read the entire response
i am new to Java but have 3 years experience in C#, i am encountering an issue where by a String is not retaining its assigned value (using Getter/Setter methods).
my object class is looking like so;
public class filePathPojo {
private String FilePath;
public void setFilePath(String _Path){
this.FilePath = _Path;
}
public String getFilePath(){
return this.FilePath;
}
}
I am having a separate class file with two methods, one is creating a Directory Route with unique value based on who is using application, it is then storing the Path using the Set, the next method is capturing a screenshot and moving to the new directory. Everytime the screenshot method is running and calling the 'Get' it is returning NULL! this is quite frustrating for something so simple.
other class looks like so
public class folderSetup extends filePathPojo {
public void SetupDirectory(String ScenarioName){
String Root = "C:\\Users\\" + SomeIdentifier + "\\GherkinEvidence\\SomeProject\\";
String Today = DateTime.now().toString("dd:MM:yyyy");
Today = Today.replace(":", "-");
String dtNOW = DateTime.now().toString("HH:mm:ss");
dtNOW = dtNOW.replace("/", "-").replace(":", "");
File file = new File(Root + Today + "\\" + dtNOW + " " + ScenarioName);
boolean dirCreated = file.mkdirs();
System.out.println("***Attemping To Create Directory: " + file.getAbsolutePath());
FilePath = file.getAbsolutePath();
setFilePath(FilePath);
}
public String takeScreenshot(String screenshotName, WebDriver driver){
String path = getFilePath();
System.out.print("Filepath for screenshot picked up is" + path);
try {
WebDriver augmentedDriver = new Augmenter().augment(driver);
File source = ((TakesScreenshot)augmentedDriver).getScreenshotAs(OutputType.FILE);
//path = "./target/screenshots/" + source.getName();
FileUtils.copyFile(source, new File(path + "\\" + screenshotName + ".png"));
}
catch(IOException e) {
//path = "Failed to capture screenshot: " + e.getMessage();
}
return path;
}
}
please done anybody have an ideas?
method calls here;
contained i Step Definitions #Before (FolderSetup)
Public Class PerformanceSteps{
#Inject private folderSetup folderSetup;
#Before
public void FolderSetup(Scenario scenario){
System.out.print("***Performing Evidence Directory Setup***");
System.out.println("ScenarioName = " + scenario.getName().toString() + "**");
folderSetup.SetupDirectory(scenario.getName());
}
}
public class Navigate extends BasePage {
#Inject private com.test.utilities.folderSetup folderSetup;
public void toAppianHomePage(){
System.out.println("Navigating to Appian URL " + LoadProperties.Appian_URL);
driver.navigate().to(LoadProperties.Appian_URL);
driver.manage().window().maximize();
folderSetup.takeScreenshot("Navigate Appian Home", driver);
}
I currently have this code, which successfully records an (mp3-)stream:
public class Recorder {
private static final int BUFFER_SIZE = 2048;
private Thread thread;
private boolean running = false;
public Recorder(URL stream, File dest) {
thread = new Thread(() -> {
try {
URLConnection connection = stream.openConnection();
InputStream inStream = connection.getInputStream();
OutputStream outStream = new FileOutputStream(dest);
byte[] buffer = new byte[BUFFER_SIZE];
int length;
System.out.println("Now recording " + stream.toString());
while ((length = inStream.read(buffer)) > 0 && running) {
outStream.write(buffer, 0, length);
}
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
});
}
public void start() {
running = true;
thread.start();
}
public void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
How do I read the MP3-tags (song title and artist name) from the stream properly? I've found a few answers on how to fetch the MP3-tags from files, but not from streaming audio.
Thanks.
You can use the mp3agic library.
A java library for reading mp3 files and reading / manipulating the ID3 tags (ID3v1 and ID3v2.2 through ID3v2.4).
If your file has ID3 tags you can do:
Mp3File mp3file = new Mp3File("src/test/resources/v1andv23tagswithalbumimage.mp3");
if (mp3file.hasId3v1Tag()) {
ID3v1 id3v1Tag = mp3file.getId3v1Tag();
System.out.println("Track: " + id3v1Tag.getTrack());
System.out.println("Artist: " + id3v1Tag.getArtist());
System.out.println("Title: " + id3v1Tag.getTitle());
System.out.println("Album: " + id3v1Tag.getAlbum());
System.out.println("Year: " + id3v1Tag.getYear());
System.out.println("Genre: " + id3v1Tag.getGenre() + " (" + id3v1Tag.getGenreDescription() + ")");
System.out.println("Comment: " + id3v1Tag.getComment());
}
The file which i am trying to store in the back end is not a valid directory.. I think the code has a Unix directory config which i need to change to make this work in your windows.
how i can identify the directory where the file is trying to be stored.
i am getting the following error.
[com.keenan.oacommon.forms.services.FormServiceImpl] [checkFileDtlPathCreateIfNotExists] - strFileMstPath is not valid
[INFO ] [java.lang.Class] [processListFiles] - strFinalUploadPath []
[INFO ] [com.keenan.oacommon.forms.services.FormServiceImpl] [verifyFilePath] - Validating path []
[ERROR] [com.keenan.oacommon.forms.services.FormServiceImpl] [verifyFilePath] - strFilePath is NULL
[ERROR] [java.lang.Class] [processListFiles] - File upload path is not valid
here is my java code..
#Override
public boolean verifyFilePath(String inFilePath) {
boolean isFilePathValid = false;
String strFilePath = inFilePath;
logger.info("Validating path [" + strFilePath + "]");
if (strFilePath == null || strFilePath.equalsIgnoreCase("")) {
logger.error("strFilePath is NULL");
isFilePathValid = false;
} else {
try {
File fileUploadDir = new File(strFilePath);
if (fileUploadDir.exists() && fileUploadDir.isDirectory()) {
logger.error("File Path [" + strFilePath + "] is good");
isFilePathValid = true;
} else {
logger.warn("File Path [" + strFilePath + "] is not valid");
isFilePathValid = false;
}
} catch (Exception e) {
isFilePathValid = false;
logger.error("Exception while validating File Path [" + strFilePath + "] - " + e.getMessage(), e);
}
}
return isFilePathValid;
}
#Override
public String checkFileDtlPathCreateIfNotExists(String inFilePath, String inAppSeqNo, String inUploadSeqNo) {
boolean isFilePathValid = false;
/* Main directory (all file uploads) */
String strFileMstPath = null;
File fileUploadMstDir = null;
/* Sub directory (file uploads per application) */
String strFileDtlAppPath = null;
File fileUploadDtlAppDir = null;
/* Sub-sub directory (file uploads per upload request) */
String strFileDtlAppUploadPath = null;
File fileUploadDtlAppUploadDir = null;
boolean fileDirExists = false;
String strFinalReturnPath = null;
if (inFilePath == null || inFilePath.equalsIgnoreCase("")) {
logger.error("inFilePath is NULL");
isFilePathValid = false;
} else {
try {
if (!inFilePath.endsWith("/"))
strFileMstPath = inFilePath + "/";
else
strFileMstPath = inFilePath;
fileUploadMstDir = new File(strFileMstPath);
if (fileUploadMstDir.exists() && fileUploadMstDir.isDirectory()) {
logger.error("strFileMstPath is good");
strFileDtlAppPath = strFileMstPath + inAppSeqNo + "/";
fileUploadDtlAppDir = new File(strFileDtlAppPath);
if (fileUploadDtlAppDir.exists() && fileUploadDtlAppDir.isDirectory()) {
fileDirExists = true;
logger.debug("fileUploadDtlAppDir [" + fileUploadDtlAppDir.toString() + "] exists and is a dir");
} else {
fileDirExists = fileUploadDtlAppDir.mkdir();
}
if (fileDirExists) {
/* Set fileDirExists to false for the next check */
fileDirExists = false;
strFileDtlAppUploadPath = strFileDtlAppPath + inUploadSeqNo + "/";
fileUploadDtlAppUploadDir = new File(strFileDtlAppUploadPath);
if (fileUploadDtlAppUploadDir.exists() && fileUploadDtlAppUploadDir.isDirectory()) {
fileDirExists = true;
logger.debug("fileUploadDtlAppUploadDir [" + fileUploadDtlAppUploadDir.toString()
+ "] exists and is a dir");
} else {
fileDirExists = fileUploadDtlAppUploadDir.mkdir();
}
strFinalReturnPath = strFileDtlAppUploadPath;
} else
logger.error("Could not create strFileDtlAppPath [" + strFileDtlAppPath
+ "] - not attempting to create strFileDtlAppUploadPath [" + strFileDtlAppUploadPath + "]");
if (fileDirExists)
isFilePathValid = true;
else
isFilePathValid = false;
} else {
logger.info("strFileMstPath is not valid");
isFilePathValid = false;
}
} catch (Exception e) {
isFilePathValid = false;
logger.error("Exception while validating filePath - " + e.getMessage(), e);
}
}
if (isFilePathValid)
return strFinalReturnPath;
else
return "";
}
#Override
#Transactional(readOnly = true)
public FileUpload getUploadedFileBySeqNo(int inFileSeqNo) {
FileUpload fileUploadInstance = null;
try {
logger.debug("Fetching FileUpload for inFileUploadSeqNo [" + inFileSeqNo + "]");
fileUploadInstance = FormsHelper.getFormDAO().getUploadedFileDetailsBySeqNo(inFileSeqNo);
logger.debug("FileUpload for inFileUploadSeqNo[" + inFileSeqNo + "] is [" + fileUploadInstance.toString() + "]");
} catch (Exception e) {
logger.error("Exceoption while fetching FileUpload for inFileUploadSeqNo [" + inFileSeqNo + "] - " + e.getMessage(), e);
fileUploadInstance = null;
}
return fileUploadInstance;
}
#Override
#Transactional(readOnly = true)
public FileUpload getUploadedFileByName(String inFileName, String inUploadSeqNo, String inAppSeqNo) {
FileUpload fileUploadInstance = null;
int uploadSeqNo = 0;
int appSeqNo = 0;
try {
uploadSeqNo = Integer.parseInt(inUploadSeqNo);
appSeqNo = Integer.parseInt(inAppSeqNo);
logger.debug("Fetching FileUpload for inFileName [" + inFileName + "]");
fileUploadInstance = FormsHelper.getFormDAO().getUploadedFileDetailsByName(inFileName, uploadSeqNo, appSeqNo);
logger.debug("FileUpload for inFileName [" + inFileName + "] is [" + fileUploadInstance.toString() + "]");
} catch (Exception e) {
logger.error("Exception while fetching FileUpload for inFileName [" + inFileName + "] - " + e.getMessage(), e);
fileUploadInstance = null;
}
return fileUploadInstance;
}
#Override
#Transactional(readOnly = false)
public boolean saveUploadedFileInfo(FileUpload inFileUpload) {
boolean fileUploadInfoSavedSuccessfully = false;
try {
if (inFileUpload == null) {
logger.error("inFileUpload is NULL / Blank");
fileUploadInfoSavedSuccessfully = false;
} else {
FormsHelper.getFormDAO().saveUploadedFileInfo(inFileUpload);
fileUploadInfoSavedSuccessfully = true;
}
} catch (Exception e) {
logger.error("Exception while saving FileUpload - " + e.getMessage(), e);
fileUploadInfoSavedSuccessfully = false;
}
return fileUploadInfoSavedSuccessfully;
}
#Override
#Transactional(readOnly = true)
public List<FileUpload> getUploadedFilesList(int inUploadSeqNo) {
List<FileUpload> uploadedFilesList = null;
try {
logger.debug("Fetching FileUpload for inFileUploadSeqNo [" + inUploadSeqNo + "]");
uploadedFilesList = FormsHelper.getFormDAO().getUploadedFilesList(inUploadSeqNo);
logger.debug("FileUpload for inUploadSeqNo [" + inUploadSeqNo + "]");
} catch (Exception e) {
logger.error("Exceoption while fetching FileUpload for inUploadSeqNo [" + inUploadSeqNo + "] - " + e.getMessage(), e);
uploadedFilesList = null;
}
return uploadedFilesList;
}
#Override
public Map<String, String> getUserNUploadDetailsForMail(int appSeqNo, String emailAddress) {
Map<String, String> details = new HashMap<String, String>();
try {
logger.debug("Fetching getUserNUploadDetailsForMail appSeqNo =[" + appSeqNo + "]" + "and emailAddress = [" + emailAddress
+ "]");
details = FormsHelper.getFormDAO().getUserNUploadDetailsForMail(appSeqNo, emailAddress);
logger.debug("Fetched details [" + details + "]");
} catch (Exception e) {
logger.error("Exceoption while fetching getUserNUploadDetailsForMail " + e.getMessage(), e);
}
return details;
}
Thanks..
Firstly, let me say I not a java programmer, I am a programmer on the IBM Iseries. However, I've been tasked with changing a current java application that currently sends a stream of data to one URL that will allow that same stream of data to be sent to multiple URLs based on a properties file. Our java app runs on the Iseries and we are using the org.apache.commons.httpclient.HttpClient class to send the data and the response is processed. Everything works great right now, but I wanted to see if anyone could point me in the right direction to complete this task.
Essentially, I need to send the same block of data to multiple URLs within the same thread or instance. I'm not sure if its possible or the best way to try to complete this. So, is there a way to create multiple instances within the same thread that will send the same data stream to multiple URLs? Before you start commenting I will say again that I am not a java programmer and I wasn't even sure how to phrase the question.
Added code sample:
public class Replication_CC implements TextProcessor {
public static String VERSION = "v2014.1.0";
static Logger log = Logger.getLogger(Replication_CC.class);
String url;
int retries = 1;
public Replication_CC(Properties p) {
super();
url = p.getProperty("url");
log.info("Service URL set to " + url);
retries = PropertiesUtil.getOptionalIntProperty(p, "retries", 1);
log.info("Retries set to " + retries);
}
public static void main(String[] args) throws Exception {
log.info("Replication " + VERSION);
log.info("Initializing...");
Properties p = PropertiesUtil.loadProperties(Replication_CC.class.getResource("/Replication_CC.properties"));
DQServer server = new DQServer(p, new Replication_CC(p));
server.run();
}
public String process(String request) throws Exception {
long processStart = System.currentTimeMillis();
String response = null;
for (int i=0; i<=retries; i++) {
try {
response = send(request, url);
if (response!=null) break;
}
catch (Exception e) {
log.warn("Error processing: " + e.getMessage());
if (i<retries) {
log.warn("Trying again (retry " + (i+1) + "...");
}
else {
log.error("Giving up on this transaction.");
break;
}
}
}
long processFinished = System.currentTimeMillis();
log.info("Request was processed in " + (processFinished-processStart) + "ms.");
return response;
}
public String send(String request, String url) throws Exception {
log.debug("Creating request...");
HttpClientParams params = new HttpClientParams();
params.setParameter("http.useragent", "http-api / Replication");
HttpClient client = new HttpClient(params);
PostMethod post = new PostMethod(url);
/*
List<NameValuePair> params = new ArrayList<NameValuePair>();
for (String key : globalRequest.keySet()) {
params.add(nvp(key, globalRequest.get(key)));
}
*/
post.setRequestBody(request);
// Log the request
if (log.isDebugEnabled()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
post.getRequestEntity().writeRequest(baos);
baos.close();
log.debug("HTTP Request: \n" + StringUtils.repeat("*", 100) + "\n" + "Content Type: "
+ post.getRequestEntity().getContentType() + "\n" + "Content Length: "
+ post.getRequestEntity().getContentLength() + "\n" + "Request Headers: "
+ ArrayUtils.toString(post.getRequestHeaders()) + "\n" + "Request Params: " + baos.toString() + "\n" +
StringUtils.repeat("*", 100));
}
try {
log.info("Sending request...");
int responseCode = client.executeMethod(post);
//log.debug(String.format("Http Response Code [%s]", responseCode));
log.debug("Http Response Code [" + responseCode + "]");
if (responseCode == HttpStatus.SC_OK) {
String charset = post.getResponseCharSet();
log.debug("Response Character Set [" + charset + "]");
/*
byte[] body = post.getResponseBody();
String response = new String(body, charset);
*/
String response = IOUtils.toString(post.getResponseBodyAsStream());
log.debug("Response Body: \n" + response);
return response;
}
else {
throw new Exception(post.getStatusLine().toString());
}
}
catch (IOException ioe) {
log.error(ioe);
throw ioe;
}
finally {
post.releaseConnection();
}
}
One simple way is to include multiple URL's in the existing url property separated by a unique character. I chose "|" (pipe) in this example because it's highly unlikely to see a pipe in a normal url.
Java identifies methods by name and parameter signature. We can use that to our advantage by adding a String url parameter to the existing process method and creating a new process(String request) method that will split and iterate over the url's. The only downside is that it will only return the last response to the DQServer class.
public String process(String request) throws Exception {
String response;
for (String u : url.split("\\|")) {
response = process(request, u);
}
return response;
}
public String process(String request, String url) throws Exception {
long processStart = System.currentTimeMillis();
String response = null;
for (int i=0; i<=retries; i++) {
try {
response = send(request, url);
if (response!=null) break;
}
catch (Exception e) {
log.warn("Error processing: " + e.getMessage());
if (i<retries) {
log.warn("Trying again (retry " + (i+1) + "...");
}
else {
log.error("Giving up on this transaction.");
break;
}
}
}
long processFinished = System.currentTimeMillis();
log.info("Request was processed in " + (processFinished-processStart) + "ms.");
return response;
}
The complete sample is available on GitHub Gist.