I had/have a java application which is loading a game, and i tried to make it into an applet and loading into a html webpage, but when i try and load it i get and error and it doesn't load, could someone please help me and tell me what i am doing wrong?
Java application code:
import java.applet.*;
import java.awt.Dimension;
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.*;
public class OSRSLoader
implements AppletStub
{
static JMenuBar menubar;
static JFrame i;
public static void main(String args[])
throws Exception
{
new OSRSLoader();
}
public OSRSLoader()
throws Exception, FileNotFoundException
{
JFrame i = new JFrame("RS Oldschool Client Beta V1:00");
i.setSize(new Dimension(763, 514));
i.setPreferredSize(new Dimension(763, 514));
JLabel label = new JLabel();
ImageIcon icon = new ImageIcon(new URL("http://www.runescape.com/image/rsp777/oldschool_ani.gif"));
icon.setImageObserver(null);
label.setIcon(icon);
i.add(label);
i.pack();
i.setVisible(true);
String str = getPageSource(new URL("http://oldschool38.runescape.com"));
Pattern pattern = Pattern.compile("gamep\\w+");
Matcher match = pattern.matcher(str);
if(match.find())
{
OSRSLoader stub = new OSRSLoader(Pattern.compile("<param name=\"([^\\s]+)\"\\s+value=\"([^>]*)\">"), str);
Download("http://oldschool38.runescape.com/", (new StringBuilder(String.valueOf(match.group(0)))).append(".jar").toString());
stub.setCodeBase(new URL((new StringBuilder("http://oldschool38.runescape.com/")).append(match.group(0)).append(".jar").toString()));
stub.setDocumentBase(new URL((new StringBuilder("http://oldschool38.runescape.com/")).append(match.group(0)).append(".jar").toString()));
stub.getParameter((String)parameters.get("java_arguments"));
URLClassLoader classLoader = new URLClassLoader(new URL[] {
new URL("file:gamepack.jar")
});
Applet applet = (Applet)classLoader.loadClass("client").newInstance();
applet.setStub(stub);
applet.setSize(new Dimension(763, 514));
applet.init();
applet.start();
i.add(applet);
i.pack();
i.setDefaultCloseOperation(3);
label.setVisible(false);
}
}
public OSRSLoader(Pattern parameterPattern, String frameSource)
{
String key;
String value;
for(Matcher param = parameterPattern.matcher(frameSource); param.find(); System.out.println((new StringBuilder("Parameter Loaded. Key = ")).append(key).append(", value =").append(value).toString()))
{
key = param.group(1);
value = param.group(2);
parameters.put(key, value);
}
}
private String getPageSource(URL url)
throws IOException, InterruptedException
{
URLConnection cn = url.openConnection();
cn.addRequestProperty("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
cn.addRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
cn.addRequestProperty("Accept-Encoding", "gzip,deflate");
cn.addRequestProperty("Accept-Language", "en-gb,en;q=0.5");
cn.addRequestProperty("Connection", "keep-alive");
cn.addRequestProperty("Host", "www.runescape.com");
cn.addRequestProperty("Keep-Alive", "300");
cn.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:9.0.1) Gecko/20100101 Firefox/9.01");
DataInputStream di = new DataInputStream(cn.getInputStream());
byte tmp[] = new byte[cn.getContentLength()];
di.readFully(tmp);
di.close();
Thread.sleep(250 + (int)Math.random() * 500);
return new String(tmp);
}
public void appletResize(int i, int j)
{
}
public void setCodeBase(URL codeBase)
{
this.codeBase = codeBase;
}
public void setDocumentBase(URL documentBase)
{
this.documentBase = documentBase;
}
public AppletContext getAppletContext()
{
return null;
}
public URL getCodeBase()
{
return codeBase;
}
public URL getDocumentBase()
{
return documentBase;
}
public String getParameter(String name)
{
return (String)parameters.get(name);
}
public boolean isActive()
{
return false;
}
public static void Download(String world, String archive)
throws Exception
{
URLConnection jarConnection = (new URL((new StringBuilder(String.valueOf(world))).append(archive).toString())).openConnection();
FileOutputStream out = new FileOutputStream("./gamepack.jar");
InputStream input = jarConnection.getInputStream();
byte info[] = new byte[1024];
int ln;
while((ln = input.read(info)) != -1)
out.write(info, 0, ln);
}
private static Map parameters = new HashMap();
private URL codeBase;
private URL documentBase;
}
Java applet code:
import java.applet.*;
import java.awt.*;
import java.io.DataInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main extends Applet implements AppletStub {
public void init() {
}
public void run() throws FileNotFoundException, Exception {
new Main();
}
public Main() throws Exception, FileNotFoundException {
String str = getPageSource(new URL("http://oldschool38.runescape.com"));
Pattern pattern = Pattern.compile("gamep\\w+");
Matcher match = pattern.matcher(str);
if(match.find())
{
Main stub = new Main(Pattern.compile("<param name=\"([^\\s]+)\"\\s+value=\"([^>]*)\">"), str);
Download("http://oldschool38.runescape.com/", (new StringBuilder(String.valueOf(match.group(0)))).append(".jar").toString());
stub.setCodeBase(new URL((new StringBuilder("http://oldschool38.runescape.com/")).append(match.group(0)).append(".jar").toString()));
stub.setDocumentBase(new URL((new StringBuilder("http://oldschool38.runescape.com/")).append(match.group(0)).append(".jar").toString()));
stub.getParameter((String)parameters.get("java_arguments"));
URLClassLoader classLoader = new URLClassLoader(new URL[] {
new URL("file:gamepack.jar")
});
Applet applet = (Applet)classLoader.loadClass("client").newInstance();
applet.setStub(stub);
applet.setPreferredSize(new Dimension(765, 503));
applet.setSize(new Dimension(765, 503));
applet.init();
applet.start();
}
}
public Main(Pattern parameterPattern, String frameSource)
{
String key;
String value;
for(Matcher param = parameterPattern.matcher(frameSource); param.find(); System.out.println((new StringBuilder("Parameter Loaded. Key = ")).append(key).append(", value =").append(value).toString()))
{
key = param.group(1);
value = param.group(2);
parameters.put(key, value);
}
}
private String getPageSource(URL url)
throws IOException, InterruptedException
{
URLConnection cn = url.openConnection();
cn.addRequestProperty("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
cn.addRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
cn.addRequestProperty("Accept-Encoding", "gzip,deflate");
cn.addRequestProperty("Accept-Language", "en-gb,en;q=0.5");
cn.addRequestProperty("Connection", "keep-alive");
cn.addRequestProperty("Host", "www.runescape.com");
cn.addRequestProperty("Keep-Alive", "300");
cn.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:9.0.1) Gecko/20100101 Firefox/9.01");
DataInputStream di = new DataInputStream(cn.getInputStream());
byte tmp[] = new byte[cn.getContentLength()];
di.readFully(tmp);
di.close();
Thread.sleep(250 + (int)Math.random() * 500);
return new String(tmp);
}
public void appletResize(int i, int j)
{
}
public void setCodeBase(URL codeBase)
{
this.codeBase = codeBase;
}
public void setDocumentBase(URL documentBase)
{
this.documentBase = documentBase;
}
public AppletContext getAppletContext()
{
return null;
}
public URL getCodeBase()
{
return codeBase;
}
public URL getDocumentBase()
{
return documentBase;
}
public String getParameter(String name)
{
return (String)parameters.get(name);
}
public boolean isActive()
{
return false;
}
public static void Download(String world, String archive)
throws Exception
{
URLConnection jarConnection = (new URL((new StringBuilder(String.valueOf(world))).append(archive).toString())).openConnection();
FileOutputStream out = new FileOutputStream("./gamepack.jar");
InputStream input = jarConnection.getInputStream();
byte info[] = new byte[1024];
int ln;
while((ln = input.read(info)) != -1)
out.write(info, 0, ln);
}
private static Map parameters = new HashMap();
private URL codeBase;
private URL documentBase;
}
The error when i try and load it in html is: java.lang.reflect.invocationtargetexception
i click details and it sais:
Java Plug-in 10.25.2.17
Using JRE version 1.7.0_25-b17 Java HotSpot(TM) Client VM
User home directory = C:\Users\Will
----------------------------------------------------
c: clear console window
f: finalize objects on finalization queue
g: garbage collect
h: display this help message
l: dump classloader list
m: print memory usage
o: trigger logging
q: hide console
r: reload policy configuration
s: dump system and deployment properties
t: dump thread list
v: dump thread stack
x: clear classloader cache
0-5: set trace level to <n>
----------------------------------------------------
Related
When I'm running a Java WebSocketStompClient, I got below error:
org.eclipse.jetty.websocket.api.MessageTooLargeException: Text message size [73728] exceeds maximum size [65536]
Sample code:
import org.apache.log4j.Logger;
import org.springframework.messaging.simp.stomp.StompFrameHandler;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.socket.WebSocketHttpHeaders;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;
import org.springframework.web.socket.sockjs.client.SockJsClient;
import org.springframework.web.socket.sockjs.client.Transport;
import org.springframework.web.socket.sockjs.client.WebSocketTransport;
import org.springframework.web.socket.sockjs.frame.Jackson2SockJsMessageCodec;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class HelloClient {
private static Logger logger = Logger.getLogger(HelloClient.class);
StompSession session;
private final static WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
public ListenableFuture<StompSession> connect() {
Transport webSocketTransport = new WebSocketTransport(new StandardWebSocketClient());
List<Transport> transports = Collections.singletonList(webSocketTransport);
SockJsClient sockJsClient = new SockJsClient(transports);
sockJsClient.setMessageCodec(new Jackson2SockJsMessageCodec());
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
long[] hb = stompClient.getDefaultHeartbeat();
boolean en = stompClient.isDefaultHeartbeatEnabled();
long timeout = stompClient.getReceiptTimeLimit();
String url = "https://www.test.com";
return stompClient.connect(url, headers, new MyHandler());
}
public void subscribeMsg(StompSession stompSession) throws ExecutionException, InterruptedException {
stompSession.subscribe("/topic/test", new StompFrameHandler() {
public Type getPayloadType(StompHeaders stompHeaders) {
return byte[].class;
}
public void handleFrame(StompHeaders stompHeaders, Object o) {
logger.info("Received message " + new String((byte[]) o));
String response = new String((byte[]) o);
}
});
}
private class MyHandler extends StompSessionHandlerAdapter {
public void afterConnected(StompSession stompSession, StompHeaders stompHeaders) {
logger.info("Now connected");
session = stompSession;
}
}
public boolean isConnected() {
try {
Thread.sleep(500);
return session != null && session.isConnected();
} catch (Exception e) {
logger.warn("Error happens when checking connection status, ", e);
return false;
}
}
public static void main(String[] args) throws Exception {
HelloClient helloClient = new HelloClient();
ListenableFuture<StompSession> f = helloClient.connect();
StompSession stompSession = f.get();
helloClient.subscribeMsg(stompSession);
while (true) {
if (!helloClient.isConnected()) {
logger.info("wss diconnected ");
logger.info("need re-create ");
}
}
}
}
How to increase the limitation for a Java stomp websocket client? I found some not related answers How can I set max buffer size for web socket client(Jetty) in Java which are not suitable for stomp websocket client.
Also tried stompClient.setInboundMessageSizeLimit(Integer.MAX_VALUE); which doesn't work.
import java.net.CookiePolicy;
import java.net.HttpCookie;
import java.net.URI;
public class NoGovernmentCookies implements CookiePolicy {
#Override
public boolean shouldAccept(URI uri, HttpCookie cookie){
if(uri.getAuthority().toLowerCase().endsWith(".gov")){
return false;
}
return true;
}
}
I have made new CookieTest class to call NoGovernmentCookies.
import java.net.*;
import java.util.List;
public class CookieTest {
public static void main(String[] args) {
CookieManager manager = new CookieManager();
HttpCookie c1 = new HttpCookie("user1", "1");
URI uri1 = URI.create("http://spm.gov");
manager.setCookiePolicy(new NoGovernmentCookies());
/* manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
manager.setCookiePolicy(CookiePolicy.ACCEPT_NONE);
manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);*/
// CookieHandler.setDefault(manager);
CookieStore cs = manager.getCookieStore();
cs. add(uri1, c1);
//read stored cookies
List cl = cs.getCookies();
System.out.println("cookies list in cookiestore" + cl + "\n");
}
}
it is showing output as value:
cookies list in cookiestore[user1="1"]
I do not want to add it in cookiestore, because it is against our NoGovernmentCookies policy for .gov.
I am creating a Web App in which, I have to upload files by splitting them using parallel processing and multi threading and while downloading I have to combine them back to a single file using multi threading and parallel processing.
I want to combine split files into a single. But its not working as I expected to work.
The number of threads created is equal to the number of parts the file have been split.
And the threads should run parallelly and should run only once. But the threads are called several times. Help me fix the code.
UploadServlet.java
import java.util.Arrays;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import org.apache.commons.io.IOUtils;
import jakarta.servlet.*;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;
import jakarta.servlet.http.HttpServletRequest;
import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class UploadServlet extends HttpServlet
{
private static final long serialVersionUID = 100L;
public static String fileName;
public static long size;
public static int noOfParts;
public static String type;
public static byte[] b;
private static final String INSERT_USERS_SQL = "INSERT INTO uploadlist" +
" (filename, filesize, noofparts) VALUES " +
"(?, ?, ?);";
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part file = request.getPart("file");
fileName=file.getSubmittedFileName();
type=file.getContentType();
PrintWriter writer=response.getWriter();
file.write(fileName);
String n = request.getParameter("parts");
size = file.getSize();
Integer temp1 = Integer.parseInt(n);
noOfParts = temp1.intValue();
set();
writer.println("File Uploaded Successfully");
file.delete();
}
public static void set()
{
Split.split(fileName,size,noOfParts);
try {
Connection c = DataBaseConnection.getConnection();
PreparedStatement preparedStatement = c.prepareStatement(INSERT_USERS_SQL);
preparedStatement.setString(1, fileName);
preparedStatement.setLong(2, size);
preparedStatement.setInt(3, noOfParts);
System.out.println(preparedStatement);
preparedStatement.executeUpdate();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
From UploadServlet Split.split() is called to split the files into number of parts.
Split.java
import java.io.*;
import java.util.Arrays;
public class Split implements Runnable
{
int i;
long size;
int noOfParts;
String fileName;
Split()
{
fileName="";
}
Split(String fileName, int i, long size, int noOfParts)
{
this.fileName=fileName;
this.i=i;
this.size=size;
this.noOfParts=noOfParts;
}
public void run()
{
try
{
System.out.println(i);
RandomAccessFile in = new RandomAccessFile("D:\\temp\\"+fileName,"r");
int bytesPerSplit = (int)(size/noOfParts);
int remainingBytes = (int)(size % noOfParts);
byte[] b;
if(i!=noOfParts-1)
{
b = new byte[bytesPerSplit];
}
else
{
b = new byte[bytesPerSplit+remainingBytes];
}
in.seek((long)i*bytesPerSplit);
in.read(b);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\Upload\\"+fileName+i+".bin"));
for(byte temp : b)
out.write(temp);
out.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void split(String fileName, long size, int noOfParts)
{
for(int i=0; i<noOfParts; i++)
{
Split obj = new Split(fileName,i,size,noOfParts);
Thread t = new Thread(obj);
t.start();
}
}
}
In this program, I split the files according to number of parts. And I want to combine them back using Parallel Processing and Multi Threading.
DownloadServlet.java\
import jakarta.servlet.http.HttpServlet;
import org.postgresql.Driver;
import java.sql.Statement;
import java.io.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.DriverManager;
import java.util.Arrays;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String name = new String(request.getParameter("fileName"));
int noOfParts = Integer.parseInt(request.getParameter("parts"));
int size = Integer.parseInt(request.getParameter("size"));
File downloadFile = new File("D:\\Download\\"+name);
Combine.combine(name,noOfParts,size);
int length = (int)downloadFile.length();
String completeFile=name;
ServletContext context=getServletContext();
String mimeType = context.getMimeType(completeFile);
if (mimeType == null)
{
mimeType = "application/octet-stream";
}
response.setContentType(mimeType);
response.setContentLength((int)length);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", completeFile);
response.setHeader(headerKey, headerValue);
OutputStream outStream = response.getOutputStream();
DataInputStream in = new DataInputStream(new FileInputStream(downloadFile));
byte[] buffer = new byte[(int)length];
while ((in != null) && ((length = in.read(buffer)) != -1))
{
outStream.write(buffer,0,length);
}
if ((length = in.read(buffer))== -1) {
outStream.write(buffer, 0, length);
}
Arrays.fill(buffer, (byte)0);
in.close();
outStream.flush();
outStream.close();
}
}
From DownloadServlet, Combine.combine() is called to combine the split parts into a single file.
Combine.java
import java.io.*;
import java.util.concurrent.TimeUnit;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
import java.util.regex.*;
import java.util.Scanner;
import java.util.Arrays;
public class Combine implements Runnable
{
String name;
int size;
int noOfParts;
int i;
public static String root = "D:\\Upload\\";
Combine(String name,int noOfParts,int size, int i)
{
this.name = name;
this.noOfParts=noOfParts;
this.size=size;
this.i=i;
}
public void run()
{
try
{
System.out.println(i);
RandomAccessFile out = new RandomAccessFile("D:\\Download\\"+name,"rw");
int bytesPerSplit = size/noOfParts;
int remainingBytes = size%noOfParts;
String temp=name+i+".bin";
RandomAccessFile file = new RandomAccessFile(root+temp,"r");
long l=file.length();
byte[] b = new byte[(int)l];
file.read(b);
out.seek(i*bytesPerSplit);
out.write(b);
file.close();
out.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void combine(String name, int noOfParts, int size)
{
for(int i=0; i<noOfParts; i++)
{
Combine obj = new Combine(name,noOfParts,size,i);
Thread t = new Thread(obj,"Thread"+i);
t.start();
}
}
}
I have attached the image in which the numbers represent the part of the file being read and combined using threads.
The output shows that the threads keeping on executing again and again.
I don't know where is the error or any logical mistake in my program.
Help me solve this problem.
I am working on code (java) that will open up a selenium headless browser with HTML Unit webdriver and then take a screenshot. Unfortunately, HTML Unit does not support screenshots on its own, so I had to download an extended version:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.internal.Base64Encoder;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class ScreenCaptureHtmlUnitDriver extends HtmlUnitDriver implements TakesScreenshot {
private static Map<String, byte[]> imagesCache = Collections.synchronizedMap(new HashMap<String, byte[]>());
private static Map<String, String> cssjsCache = Collections.synchronizedMap(new HashMap<String, String>());
// http://stackoverflow.com/questions/4652777/java-regex-to-get-the-urls-from-css
private final static Pattern cssUrlPattern = Pattern.compile("background(-image)?[\\s]*:[^url]*url[\\s]*\\([\\s]*([^\\)]*)[\\s]*\\)[\\s]*");// ?<url>
public ScreenCaptureHtmlUnitDriver() {
super();
}
public ScreenCaptureHtmlUnitDriver(boolean enableJavascript) {
super(enableJavascript);
}
public ScreenCaptureHtmlUnitDriver(Capabilities capabilities) {
super(capabilities);
}
public ScreenCaptureHtmlUnitDriver(BrowserVersion version) {
super(version);
DesiredCapabilities var = ((DesiredCapabilities) getCapabilities());
var.setCapability(CapabilityType.TAKES_SCREENSHOT, true);
}
//#Override
#SuppressWarnings("unchecked")
public <X> X getScreenshotAs(OutputType<X> target) throws WebDriverException {
byte[] archive = new byte[0];
try {
archive = downloadCssAndImages(getWebClient(), (HtmlPage) getCurrentWindow().getEnclosedPage());
} catch (Exception e) {
}
if(target.equals(OutputType.BASE64)){
return target.convertFromBase64Png(new Base64Encoder().encode(archive));
}
if(target.equals(OutputType.BYTES)){
return (X) archive;
}
return (X) archive;
}
// http://stackoverflow.com/questions/2244272/how-can-i-tell-htmlunits-webclient-to-download-images-and-css
protected byte[] downloadCssAndImages(WebClient webClient, HtmlPage page) throws Exception {
WebWindow currentWindow = webClient.getCurrentWindow();
Map<String, String> urlMapping = new HashMap<String, String>();
Map<String, byte[]> files = new HashMap<String, byte[]>();
WebWindow window = null;
try {
window = webClient.getWebWindowByName(page.getUrl().toString()+"_screenshot");
webClient.getPage(window, new WebRequest(page.getUrl()));
} catch (Exception e) {
window = webClient.openWindow(page.getUrl(), page.getUrl().toString()+"_screenshot");
}
String xPathExpression = "//*[name() = 'img' or name() = 'link' and (#type = 'text/css' or #type = 'image/x-icon') or #type = 'text/javascript']";
List<?> resultList = page.getByXPath(xPathExpression);
Iterator<?> i = resultList.iterator();
while (i.hasNext()) {
try {
HtmlElement el = (HtmlElement) i.next();
String resourceSourcePath = el.getAttribute("src").equals("") ? el.getAttribute("href") : el
.getAttribute("src");
if (resourceSourcePath == null || resourceSourcePath.equals(""))
continue;
URL resourceRemoteLink = page.getFullyQualifiedUrl(resourceSourcePath);
String resourceLocalPath = mapLocalUrl(page, resourceRemoteLink, resourceSourcePath, urlMapping);
urlMapping.put(resourceSourcePath, resourceLocalPath);
if (!resourceRemoteLink.toString().endsWith(".css")) {
byte[] image = downloadImage(webClient, window, resourceRemoteLink);
files.put(resourceLocalPath, image);
} else {
String css = downloadCss(webClient, window, resourceRemoteLink);
for (String cssImagePath : getLinksFromCss(css)) {
URL cssImagelink = page.getFullyQualifiedUrl(cssImagePath.replace("\"", "").replace("\'", "")
.replace(" ", ""));
String cssImageLocalPath = mapLocalUrl(page, cssImagelink, cssImagePath, urlMapping);
files.put(cssImageLocalPath, downloadImage(webClient, window, cssImagelink));
}
files.put(resourceLocalPath, replaceRemoteUrlsWithLocal(css, urlMapping)
.replace("resources/", "./").getBytes());
}
} catch (Exception e) {
}
}
String pagesrc = replaceRemoteUrlsWithLocal(page.getWebResponse().getContentAsString(), urlMapping);
files.put("page.html", pagesrc.getBytes());
webClient.setCurrentWindow(currentWindow);
return createZip(files);
}
String downloadCss(WebClient webClient, WebWindow window, URL resourceUrl) throws Exception {
if (cssjsCache.get(resourceUrl.toString()) == null) {
cssjsCache.put(resourceUrl.toString(), webClient.getPage(window, new WebRequest(resourceUrl))
.getWebResponse().getContentAsString());
}
return cssjsCache.get(resourceUrl.toString());
}
byte[] downloadImage(WebClient webClient, WebWindow window, URL resourceUrl) throws Exception {
if (imagesCache.get(resourceUrl.toString()) == null) {
imagesCache.put(
resourceUrl.toString(),
IOUtils.toByteArray(webClient.getPage(window, new WebRequest(resourceUrl)).getWebResponse()
.getContentAsStream()));
}
return imagesCache.get(resourceUrl.toString());
}
public static byte[] createZip(Map<String, byte[]> files) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zipfile = new ZipOutputStream(bos);
Iterator<String> i = files.keySet().iterator();
String fileName = null;
ZipEntry zipentry = null;
while (i.hasNext()) {
fileName = i.next();
zipentry = new ZipEntry(fileName);
zipfile.putNextEntry(zipentry);
zipfile.write(files.get(fileName));
}
zipfile.close();
return bos.toByteArray();
}
List<String> getLinksFromCss(String css) {
List<String> result = new LinkedList<String>();
Matcher m = cssUrlPattern.matcher(css);
while (m.find()) { // find next match
result.add( m.group(2));
}
return result;
}
String replaceRemoteUrlsWithLocal(String source, Map<String, String> replacement) {
for (String object : replacement.keySet()) {
// background:url(http://org.com/images/image.gif)
source = source.replace(object, replacement.get(object));
}
return source;
}
String mapLocalUrl(HtmlPage page, URL link, String path, Map<String, String> replacementToAdd) throws Exception {
String resultingFileName = "resources/" + FilenameUtils.getName(link.getFile());
replacementToAdd.put(path, resultingFileName);
return resultingFileName;
}
}
Anyway, I found this code, but I am unsure how to use this code to actually take a screenshot.
I would like the screenshot to be a .jpg and to be able to be stored in a certain folder.
In the long haul, I am also going to need to run the screenshot code repeatedly.
Any help would be appreciated.
I've got the following code for a file upload with Apache's HTTP-Client (org.apache.http.client):
public static void main(String[] args) throws Exception
{
String fileName = "test.avi";
File file = new File(fileName);
String serverResponse = null;
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
HttpPut put = new HttpPut("http://localhost:8080/" + fileName);
FileEntity fileEntity = new FileEntity(file, "binary/octet-stream");
put.setEntity(fileEntity);
HttpResponse response = client.execute(put);
HttpEntity entity = response.getEntity();
if (entity != null)
{
serverResponse = EntityUtils.toString(entity);
System.out.println(serverResponse);
}
}
It work's quite well but now I want to have a progress bar which shows the progress of the file upload. How can this be made? I found a code snippet at File Upload with Java (with progress bar) but it is designed for Apache HTTP Client 3 (org.apache.commons.httpclient) and the RequestEntity class does not exist in Apache HTTP Client 4. ;(
Maybe someone of you has an approach?
Many greetings
Benny
I introduced a derived FileEntity that just counts the written bytes.
It uses OutputStreamProgress that does the actual counting (kind of a decorator to the actual OutputStream).
The advantage of this (and decoration in general) is that I do not need to copy the actual implementation, like the the actual copying from the file stream to the output stream. I can also change to use a different (newer) implementation, like the NFileEntity.
Enjoy...
FileEntity.java
public class FileEntity extends org.apache.http.entity.FileEntity {
private OutputStreamProgress outstream;
public FileEntity(File file, String contentType) {
super(file, contentType);
}
#Override
public void writeTo(OutputStream outstream) throws IOException {
this.outstream = new OutputStreamProgress(outstream);
super.writeTo(this.outstream);
}
/**
* Progress: 0-100
*/
public int getProgress() {
if (outstream == null) {
return 0;
}
long contentLength = getContentLength();
if (contentLength <= 0) { // Prevent division by zero and negative values
return 0;
}
long writtenLength = outstream.getWrittenLength();
return (int) (100*writtenLength/contentLength);
}
}
OutputStreamProgress.java
public class OutputStreamProgress extends OutputStream {
private final OutputStream outstream;
private volatile long bytesWritten=0;
public OutputStreamProgress(OutputStream outstream) {
this.outstream = outstream;
}
#Override
public void write(int b) throws IOException {
outstream.write(b);
bytesWritten++;
}
#Override
public void write(byte[] b) throws IOException {
outstream.write(b);
bytesWritten += b.length;
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
outstream.write(b, off, len);
bytesWritten += len;
}
#Override
public void flush() throws IOException {
outstream.flush();
}
#Override
public void close() throws IOException {
outstream.close();
}
public long getWrittenLength() {
return bytesWritten;
}
}
A new version using the package org.apache.commons.io.output from commons-io (2.4) and its class CountingOutputStream.
I changed the initial code to reflect my project needs to use a multipart form as input and the post method (this dues to the requirements imposed by the server side).
Consider that the delta of large file correspond in my tests to 4096 bytes. This means that the listener method counterChanged() is called every 4096 bytes of transfered data, what is acceptable for my use case.
The method looks like:
public void post(String url, File sendFile) {
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost(url + "/" + sendFile.getName());
MultipartEntity multiEntity = new MultipartEntity();
MyFileBody fileBody = new MyFileBody(sendFile);
fileBody.setListener(new IStreamListener(){
#Override
public void counterChanged(int delta) {
// do something
System.out.println(delta);
}});
multiEntity.addPart("file", fileBody);
StringBody stringBody = new StringBody(sendFile.getName());
multiEntity.addPart("fileName", stringBody);
post.setEntity(multiEntity);
HttpResponse response = client.execute(post);
}
The class MyFileBody becomes:
public class MyFileBody extends FileBody {
private IStreamListener listener;
public MyFileBody(File file) {
super(file);
}
#Override
public void writeTo(OutputStream out) throws IOException {
CountingOutputStream output = new CountingOutputStream(out) {
#Override
protected void beforeWrite(int n) {
if (listener != null && n != 0)
listener.counterChanged(n);
super.beforeWrite(n);
}
};
super.writeTo(output);
}
public void setListener(IStreamListener listener) {
this.listener = listener;
}
public IStreamListener getListener() {
return listener;
}
}
Finally, the listener interface looks like:
public interface IStreamListener {
void counterChanged(int delta);
}
This answer extends kilaka's answer by adding a simple listener to the OutputStreamProgress.java class instead of having the public getProgress() method (I'm honestly not sure how you are suppose to call the getProgress() method since the thread will be executing inside of httpclient's code the entire time you might want to call getProgress()!).
Please note you'll need to extend the entity class for each entity type you want to use, and when you write your HttpClient code, you'll need to create the entity of that new type.
I wrote a very basic write listener that implements the WriteListener interface. This is where you'll add your logic to do something with the write reports from the OutputStreamProgress, something like updating a progress bar :)
Big thanks to kilaka for using the decorator idea to sneak in a counting outstream.
WriteLisener.java
public interface WriteListener {
void registerWrite(long amountOfBytesWritten);
}
OutputStreamProgress.java
import java.io.IOException;
import java.io.OutputStream;
public class OutputStreamProgress extends OutputStream {
private final OutputStream outstream;
private long bytesWritten=0;
private final WriteListener writeListener;
public OutputStreamProgress(OutputStream outstream, WriteListener writeListener) {
this.outstream = outstream;
this.writeListener = writeListener;
}
#Override
public void write(int b) throws IOException {
outstream.write(b);
bytesWritten++;
writeListener.registerWrite(bytesWritten);
}
#Override
public void write(byte[] b) throws IOException {
outstream.write(b);
bytesWritten += b.length;
writeListener.registerWrite(bytesWritten);
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
outstream.write(b, off, len);
bytesWritten += len;
writeListener.registerWrite(bytesWritten);
}
#Override
public void flush() throws IOException {
outstream.flush();
}
#Override
public void close() throws IOException {
outstream.close();
}
}
BasicWriteListener
public class BasicWriteListener implements WriteListener {
public BasicWriteListener() {
// TODO Auto-generated constructor stub
}
public void registerWrite(long amountOfBytesWritten) {
System.out.println(amountOfBytesWritten);
}
}
MultipartEntityWithProgressBar
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
public class MultipartEntityWithProgressBar extends MultipartEntity {
private OutputStreamProgress outstream;
private WriteListener writeListener;
#Override
public void writeTo(OutputStream outstream) throws IOException {
this.outstream = new OutputStreamProgress(outstream, writeListener);
super.writeTo(this.outstream);
}
public MultipartEntityWithProgressBar(WriteListener writeListener)
{
super();
this.writeListener = writeListener;
}
public MultipartEntityWithProgressBar(HttpMultipartMode mode, WriteListener writeListener)
{
super(mode);
this.writeListener = writeListener;
}
public MultipartEntityWithProgressBar(HttpMultipartMode mode, String boundary, Charset charset, WriteListener writeListener)
{
super(mode, boundary, charset);
this.writeListener = writeListener;
}
// Left in for clarity to show where I took from kilaka's answer
// /**
// * Progress: 0-100
// */
// public int getProgress() {
// if (outstream == null) {
// return 0;
// }
// long contentLength = getContentLength();
// if (contentLength <= 0) { // Prevent division by zero and negative values
// return 0;
// }
// long writtenLength = outstream.getWrittenLength();
// return (int) (100*writtenLength/contentLength);
// }
}
Hello guys!
I solved the problem myself and made a simple example to it.
If there are any questions, feel free to ask.
Here we go!
ApplicationView.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;
public class ApplicationView implements ActionListener
{
File file = new File("C:/Temp/my-upload.avi");
JProgressBar progressBar = null;
public ApplicationView()
{
super();
}
public void createView()
{
JFrame frame = new JFrame("File Upload with progress bar - Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 300, 200);
frame.setVisible(true);
progressBar = new JProgressBar(0, 100);
progressBar.setBounds(20, 20, 200, 30);
progressBar.setStringPainted(true);
progressBar.setVisible(true);
JButton button = new JButton("upload");
button.setBounds(progressBar.getX(),
progressBar.getY() + progressBar.getHeight() + 20,
100,
40);
button.addActionListener(this);
JPanel panel = (JPanel) frame.getContentPane();
panel.setLayout(null);
panel.add(progressBar);
panel.add(button);
panel.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
try
{
sendFile(this.file, this.progressBar);
}
catch (Exception ex)
{
System.out.println(ex.getLocalizedMessage());
}
}
private void sendFile(File file, JProgressBar progressBar) throws Exception
{
String serverResponse = null;
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
HttpPut put = new HttpPut("http://localhost:8080/" + file.getName());
ProgressBarListener listener = new ProgressBarListener(progressBar);
FileEntityWithProgressBar fileEntity = new FileEntityWithProgressBar(file, "binary/octet-stream", listener);
put.setEntity(fileEntity);
HttpResponse response = client.execute(put);
HttpEntity entity = response.getEntity();
if (entity != null)
{
serverResponse = EntityUtils.toString(entity);
System.out.println(serverResponse);
}
}
}
FileEntityWithProgressBar.java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.http.entity.AbstractHttpEntity;
/**
* File entity which supports a progress bar.<br/>
* Based on "org.apache.http.entity.FileEntity".
* #author Benny Neugebauer (www.bennyn.de)
*/
public class FileEntityWithProgressBar extends AbstractHttpEntity implements Cloneable
{
protected final File file;
private final ProgressBarListener listener;
private long transferredBytes;
public FileEntityWithProgressBar(final File file, final String contentType, ProgressBarListener listener)
{
super();
if (file == null)
{
throw new IllegalArgumentException("File may not be null");
}
this.file = file;
this.listener = listener;
this.transferredBytes = 0;
setContentType(contentType);
}
public boolean isRepeatable()
{
return true;
}
public long getContentLength()
{
return this.file.length();
}
public InputStream getContent() throws IOException
{
return new FileInputStream(this.file);
}
public void writeTo(final OutputStream outstream) throws IOException
{
if (outstream == null)
{
throw new IllegalArgumentException("Output stream may not be null");
}
InputStream instream = new FileInputStream(this.file);
try
{
byte[] tmp = new byte[4096];
int l;
while ((l = instream.read(tmp)) != -1)
{
outstream.write(tmp, 0, l);
this.transferredBytes += l;
this.listener.updateTransferred(this.transferredBytes);
}
outstream.flush();
}
finally
{
instream.close();
}
}
public boolean isStreaming()
{
return false;
}
#Override
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
ProgressBarListener.java
import javax.swing.JProgressBar;
public class ProgressBarListener
{
private int transferedMegaBytes = 0;
private JProgressBar progressBar = null;
public ProgressBarListener()
{
super();
}
public ProgressBarListener(JProgressBar progressBar)
{
this();
this.progressBar = progressBar;
}
public void updateTransferred(long transferedBytes)
{
transferedMegaBytes = (int) (transferedBytes / 1048576);
this.progressBar.setValue(transferedMegaBytes);
this.progressBar.paint(progressBar.getGraphics());
System.out.println("Transferred: " + transferedMegaBytes + " Megabytes.");
}
}
Happy Coding!