public final class MyScreen extends MainScreen {
/**
* Creates a new MyScreen object
*/
public MyScreen() {
MyScreen myScreen = new MyScreen();
String a = myScreen.getPage("http://www.google.com");
System.out.println("+++ " + a);
}
public void parse(String xml) {
}
public String getPage(String url) {
String response = "";
try {
StreamConnection s = (StreamConnection) Connector.open(url);
InputStream input = s.openInputStream();
byte[] data = new byte[256];
int len = 0;
StringBuffer raw = new StringBuffer();
while (-1 != (len = input.read(data))) {
raw.append(new String(data, 0, len));
}
response = raw.toString();
input.close();
s.close();
} catch (Exception e) {}
return response;
}
}
When I execute this program in my Blackberry simulator, I get a StackOverflow error.
How might I resolve this?
checkout this :
1). Http connection error on the blackberry real device
2). http://docs.blackberry.com/en/developers/deliverables/11938/CS_create_first_available_HTTP_connection_857706_11.jsp
this may help you.
Related
public class helloWorldClient {
public static void main(String[] args) {
helloWorldClient crunchifyClient = new helloWorldClient();
crunchifyClient.getResponse();
}
private void getResponse() {
try {
Client client = Client.create();
WebResource webResource2 = client.resource("http://localhost:8080/Downloader/webapi/folder/zipFile");
ClientResponse response2 = webResource2.accept("application/zip").get(ClientResponse.class);
if (response2.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response2.getStatus());
}
String output2 = response2.getEntity(String.class);
System.out.println("\n============RESPONSE============");
System.out.println(output2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
This program returning an unreadable output. but when I hit that URL "http://localhost:8080/Downloader/webapi/folder/zipFile" in browser "server.zip" file is getting downloaded.
My question is how can I read that response and write to some folder through java client program?
You can get the InputStream instead of String. Then just do your basic IO.
InputStream output2 = response2.getEntity(InputStream.class);
FileOutputStream out = new FileOutputStream(file);
// do io writing
// close streams
InputStream output2 = response2.getEntity(InputStream.class);
OutputStream out = new FileOutputStream(new File("/home/mpasala/Downloads/demo.zip"));
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = output2.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
output2.close();
out.close();
System.out.println("Done!");
Thanks to https://stackoverflow.com/users/2587435/peeskillet .
I am using RestEasy client to retrieve a list of entities from web server. This is my code:
#ApplicationScoped
public class RestHttpClient {
private ResteasyClient client;
#Inject
private ObjectMapper mapper;
#PostConstruct
public void initialize() {
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 5000);
HttpClient httpClient = new DefaultHttpClient(params);
this.client = new ResteasyClientBuilder().httpEngine(new ApacheHttpClient4Engine(httpClient)).build();
}
public <E> List<E> getList(final Class<E> resultClass, final String path,
MultivaluedMap<String, Object> queryParams) {
ResteasyWebTarget target = this.client.target(path);
Response response = null;
try {
response = target.queryParams(queryParams).request().get();
String jsonString = response.readEntity(String.class);
TypeFactory typeFactory = TypeFactory.defaultInstance();
List<E> list = this.mapper.readValue(
jsonString, typeFactory.constructCollectionType(ArrayList.class, resultClass));
return list;
} catch (Exception e) {
// Handle exception
} finally {
if (response != null)
response.close();
}
return null;
}
}
It works fine, but... if I call getList() method multiple times in quick succession, sometimes I get the error "Invalid use of BasicClientConnManager: connection still allocated". I can make the same sequence of calls over and over again, and it works at least 90% of the time, so it appears to be a race condition. I am closing the Response object in finally block, which should be enough to release all resources, but apparently it isn't. What else do I have to do to make sure the connection is released? I have found some answers on the net, but they are either too old or not RestEasy-specific. I am using resteasy-client 3.0.4.Final.
I guess you only have one instance of your class RestHttpClient, and all threads/requests are using the same object.
The default ResteasyClientBuilder does not use a connection pool. Which means you can have only one parallel connection at a time. A request needs to be returned before you can use the ResteasyClient a second time (error message "connection still allocated"). You can avoid that by increasing the connection pool size:
ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder();
clientBuilder = clientBuilder.connectionPoolSize( 20 );
ResteasyWebTarget target = clientBuilder.build().target( "http://your.host" );
I am using the following RestClientFactory to set up a new client. It gives you a debug output of the raw response, specifies the keystore (needed for client ssl certificates), a connection pool and the option for the use of a proxy.
public class RestClientFactory {
public static class Options {
private final String baseUri;
private final String proxyHostname;
private final String proxyPort;
private final String keystore;
private final String keystorePassword;
private final String connectionPoolSize;
private final String connectionTTL;
public Options(String baseUri, String proxyHostname, String proxyPort) {
this.baseUri = baseUri;
this.proxyHostname = proxyHostname;
this.proxyPort = proxyPort;
this.connectionPoolSize = "100";
this.connectionTTL = "500";
this.keystore = System.getProperty( "javax.net.ssl.keyStore" );
this.keystorePassword = System.getProperty( "javax.net.ssl.keyStorePassword" );
}
public Options(String baseUri, String proxyHostname, String proxyPort, String keystore, String keystorePassword, String connectionPoolSize, String connectionTTL) {
this.baseUri = baseUri;
this.proxyHostname = proxyHostname;
this.proxyPort = proxyPort;
this.connectionPoolSize = connectionPoolSize;
this.connectionTTL = connectionTTL;
this.keystore = keystore;
this.keystorePassword = keystorePassword;
}
}
private static Logger log = LoggerFactory.getLogger( RestClientFactory.class );
public static <T> T createClient(Options options, Class<T> proxyInterface) throws Exception {
log.info( "creating ClientBuilder using options {}", ReflectionToStringBuilder.toString( options ) );
ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder();
ResteasyProviderFactory providerFactory = new ResteasyProviderFactory();
RegisterBuiltin.register( providerFactory );
providerFactory.getClientReaderInterceptorRegistry().registerSingleton( new ReaderInterceptor() {
#Override
public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
if (log.isDebugEnabled()) {
InputStream is = context.getInputStream();
String responseBody = IOUtils.toString( is );
log.debug( "received response:\n{}\n\n", responseBody );
context.setInputStream( new ByteArrayInputStream( responseBody.getBytes() ) );
}
return context.proceed();
}
} );
clientBuilder.providerFactory( providerFactory );
if (StringUtils.isNotBlank( options.proxyHostname ) && StringUtils.isNotBlank( options.proxyPort )) {
clientBuilder = clientBuilder.defaultProxy( options.proxyHostname, Integer.parseInt( options.proxyPort ) );
}
// why the fuck do you have to specify the keystore with RestEasy?
// not setting the keystore will result in not using the global one
if ((StringUtils.isNotBlank( options.keystore )) && (StringUtils.isNotBlank( options.keystorePassword ))) {
KeyStore ks;
ks = KeyStore.getInstance( KeyStore.getDefaultType() );
FileInputStream fis = new FileInputStream( options.keystore );
ks.load( fis, options.keystorePassword.toCharArray() );
fis.close();
clientBuilder = clientBuilder.keyStore( ks, options.keystorePassword );
// Not catching these exceptions on purpose
}
if (StringUtils.isNotBlank( options.connectionPoolSize )) {
clientBuilder = clientBuilder.connectionPoolSize( Integer.parseInt( options.connectionPoolSize ) );
}
if (StringUtils.isNotBlank( options.connectionTTL )) {
clientBuilder = clientBuilder.connectionTTL( Long.parseLong( options.connectionTTL ), TimeUnit.MILLISECONDS );
}
ResteasyWebTarget target = clientBuilder.build().target( options.baseUri );
return target.proxy( proxyInterface );
}
}
An example client interface:
public interface SimpleClient
{
#GET
#Path("basic")
#Produces("text/plain")
String getBasic();
}
Create a client:
SimpleClient client = RestClientFactory.createClient(
new RestClientFactory.Options(
"https://your.service.host",
"proxyhost",
"8080",
"keystore.jks",
"changeit",
"20",
"500"
)
,SimpleClient.class
);
See also:
http://docs.jboss.org/resteasy/docs/3.0-beta-3/userguide/html/RESTEasy_Client_Framework.html#d4e2049
I am Using GCM (Google Cloud Messaging).In that what i want i want to send J Son from the server side .On Client side I want to receive that for simple message i have done but i am stucked how could i pass J Son from the server side to the client side.
Please help me to resolve this.
This is my Server side code
public class GCMBroadcast extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String SENDER_ID = "";
private static final String ANDROID_DEVICE = "";
private List<String> androidTargets = new ArrayList<String>();
public GCMBroadcast() {
super();
androidTargets.add(ANDROID_DEVICE);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String collapseKey = "";
String userMessage = "";
try {
userMessage = request.getParameter("Message");
collapseKey = request.getParameter("CollapseKey");
} catch (Exception e) {
e.printStackTrace();
return;
}
Sender sender = new Sender(SENDER_ID);
Message message = new Message.Builder()
.collapseKey(collapseKey)
.addData("message", userMessage)
.build();
try {
MulticastResult result = sender.send(message, androidTargets, 1);
System.out.println("Response: " + result.getResults().toString());
if (result.getResults() != null) {
int canonicalRegId = result.getCanonicalIds();
if (canonicalRegId != 0) {
System.out.println("response " +canonicalRegId );
}
} else {
int error = result.getFailure();
System.out.println("Broadcast failure: " + error);
}
} catch (Exception e) {
e.printStackTrace();
}
request.setAttribute("CollapseKey", collapseKey);
request.setAttribute("Message", userMessage);
request.getRequestDispatcher("XX.jsp").forward(request, response);
}
}
Your payload (added to the Message by calls to addData) can only be name/value pairs. If you want to send a JSON, you can put a JSON string in the value of such name/value pair. Then you'll have to parse that JSON yourself in the client side.
For example :
.addData("message","{\"some_json_key\":\"some_json_value\"}")
We have a JavaEE application that uses jython to execute some python scripts. By and by the used heapspace gets bigger and bigger until there is no more heapspace left. In a heapdump i can se that there are a lot of Py*-classes.
So i wrote a small test-program:
TestApp
public class TestApp {
private final ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
private HashMap<String, ScriptEngine> scriptEngines = new HashMap<String, ScriptEngine>();
private final String scriptContainerPath = "";
public static void main(String[] args) throws InterruptedException {
int counter = 1;
while(true) {
System.out.println("iteration: " + counter);
TestApp testApp = new TestApp();
testApp.execute();
counter++;
Thread.sleep(100);
}
}
void execute() {
File scriptContainer = new File(scriptContainerPath);
File[] scripts = scriptContainer.listFiles();
if (scripts != null && scripts.length > 0) {
Arrays.sort(scripts, new Comparator<File>() {
#Override
public int compare(File file1, File file2) {
return file1.getName().compareTo(file2.getName());
}
});
for (File script : scripts) {
String engineName = ScriptExecutor.getEngineNameByExtension(script.getName());
if(!scriptEngines.containsKey(engineName)) {
scriptEngines.put(engineName, scriptEngineManager.getEngineByName(engineName));
}
ScriptEngine scriptEngine = scriptEngines.get(engineName);
try {
ScriptExecutor scriptExecutor = new ScriptExecutor(scriptEngine, script, null);
Boolean disqualify = scriptExecutor.getBooleanScriptValue("disqualify");
String reason = scriptExecutor.getStringScriptValue("reason");
System.out.println("disqualify: " + disqualify);
System.out.println("reason: " + reason);
} catch (Exception e) {
e.printStackTrace();
}
}
// cleanup
for(Map.Entry<String, ScriptEngine> entry : scriptEngines.entrySet()) {
ScriptEngine engine = entry.getValue();
engine.getContext().setErrorWriter(null);
engine.getContext().setReader(null);
engine.getContext().setWriter(null);
}
}
}
}
ScriptExecutor
public class ScriptExecutor {
private final static String pythonExtension = "py";
private final static String pythonEngine = "python";
private final ScriptEngine scriptEngine;
public ScriptExecutor(ScriptEngine se, File file, Map<String, Object> keyValues) throws FileNotFoundException, ScriptException {
scriptEngine = se;
if (keyValues != null) {
for (Map.Entry<String, Object> entry : keyValues.entrySet()) {
scriptEngine.put(entry.getKey(), entry.getValue());
}
}
// execute script
Reader reader = null;
try {
reader = new FileReader(file);
scriptEngine.eval(reader);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// nothing to do
}
}
}
}
public Boolean getBooleanScriptValue(String key) {
// convert Object to Boolean
}
public String getStringScriptValue(String key) {
// convert Object to String
}
public static String getEngineNameByExtension(String fileName) {
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
if (pythonExtension.equalsIgnoreCase(extension)) {
System.out.println("Found engine " + pythonEngine + " for extension " + extension + ".");
return pythonEngine;
}
throw new RuntimeException("No suitable engine found for extension " + extension);
}
}
In the specified directory are 14 python scripts that all look like this:
disqualify = True
reason = "reason"
I start this program with the following VM-arguments:
-Xrs -Xms16M -Xmx16M -XX:MaxPermSize=32M -XX:NewRatio=3 -Dsun.rmi.dgc.client.gcInterval=300000 -Dsun.rmi.dgc.server.gcInterval=300000 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -server
These are the arguments our AppServer is running with. Only Xms, Xmx and MaxPermSize are smaller in my testcase.
When I run this application I can see that the CMS Old Gen pool increases to its max size. After that the Par Eden Space pool increases. In addition at any time the ParNewGC does not run anymore. The cleanup part improved the situation but didn't resolve the problem. Has anybody an idea why my heap isn't completly cleaned?
I think I have found a solution for my problem: I removed the JSR223 stuff und now use the PythonInterpreter directly.
I would like to log some information in case of fault.
In particular I'd like to log the ip address and port of the client contacting the server, the username if the security in active, and, if possible, also the incoming message.
I added an interceptor in the getOutFaultInterceptors chain of the endpoint, but in the handleMessage I don't know which properties I can use.
Some ideas?
Thank you
In your endpoint xml definition, you could add the following to log incoming messages:
<bean id="logInInterceptor"
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<jaxws:inInterceptors>
<ref bean="logInInterceptor"/>
</jaxws:inInterceptors>
and then use the bus to limit how many characters you want logged:
<cxf:bus>
<cxf:features>
<cxf:logging limit="102400"/>
</cxf:features>
<cxf:bus>
You haven't mentioned what your method of authentication is, so ff you are using an implementation of UsernameTokenValidator, you could log the incoming username there.
To log details like the client's ip address and port, extend LoggingInInterceptor, then use the following code in handleMessage():
handleMessage() {
HttpServletRequest request =
(HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST);
if (null != request) {
String clientAddress = request.getRemoteAddr();
int remotePort = request.getRemotePort();
// log them
}
}
Also have a look at this thread.
I solved in this way
public FaultInterceptor() {
super(Phase.MARSHAL);
}
public void handleMessage(SoapMessage message) throws Fault {
Fault fault = (Fault) message.getContent(Exception.class);
Message inMessage = message.getExchange().getInMessage();
if (inMessage == null) return;
String xmlMessage = null;
InputStream is = inMessage.getContent(InputStream.class);
String rawXml = null;
if (is != null) {
rawXml = is.toString();
}
String username = null;
if (rawXml != null && rawXml.length() > 0) {
try {
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression xpathExpression;
xpathExpression = xpath.compile("//*[local-name()=\'Envelope\']/*[local-name()=\'Header\']/*[local-name()=\'Security\']" +
"/*[local-name()=\'UsernameToken\']/*[local-name()=\'Username\']");
InputSource source = new InputSource(new StringReader(rawXml));
username = xpathExpression.evaluate(source);
} catch (XPathExpressionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
xmlMessage = XMLUtils.prittyPrinter(is.toString());
}
String clientAddress = "<unknown>";
int clientPort = -1;
HttpServletRequest request = (HttpServletRequest)inMessage.get(AbstractHTTPDestination.HTTP_REQUEST);
if (null != request) {
clientAddress = request.getRemoteAddr();
clientPort = request.getRemotePort();
}
logger.warn("User: " + username + " [" + clientAddress + ":" + clientPort + "] caused fault: " + fault +
"\nMessage received: \n" + xmlMessage);
}
I found the "inMessage" property and on it I found the original message (and I can retrieve the username) and the "request" from which I retrieved the host and port.
Thank you.
I think you should view the request input stream as consumed when handling the fault.
I suggest you always log the incoming message, and extract some kind of message correlation id - for example username. Keep it as a Message header.
For fault logging, use a fault interceptor which is limited to looking at the input request.
Tie regular + fault logging together with the message correlation id.
Log the full soap request, not just the payload. Soap requests might have headers in addition to the body.
See this question for regular logging, add in addition an output fault interceptor like so:
public class SoapFaultLoggingOutInterceptor extends AbstractPhaseInterceptor<Message> {
private static final String LOCAL_NAME = "MessageID";
private static final int PROPERTIES_SIZE = 128;
private String name = "<interceptor name not set>";
protected Logger logger = null;
protected Level level;
public SoapFaultLoggingOutInterceptor() {
this(LogUtils.getLogger(SoapFaultLoggingOutInterceptor.class), Level.WARNING);
}
public SoapFaultLoggingOutInterceptor(Logger logger, Level reformatSuccessLevel) {
super(Phase.MARSHAL);
this.logger = logger;
this.level = reformatSuccessLevel;
}
public void setName(String name) {
this.name = name;
}
public void handleMessage(Message message) throws Fault {
if (!logger.isLoggable(level)) {
return;
}
StringBuilder buffer = new StringBuilder(PROPERTIES_SIZE);
// perform local logging - to the buffer
buffer.append(name);
logProperties(buffer, message);
logger.log(level, buffer.toString());
}
/**
* Gets theMessageID header in the list of headers.
*
*/
protected String getIdHeader(Message message) {
return getHeader(message, LOCAL_NAME);
}
protected String getHeader(Message message, String name) {
List<Header> headers = (List<Header>) message.get(Header.HEADER_LIST);
if(headers != null) {
for(Header header:headers) {
if(header.getName().getLocalPart().equalsIgnoreCase(name)) {
return header.getObject().toString();
}
}
}
return null;
}
protected void logProperties(StringBuilder buffer, Message message) {
final String messageId = getIdHeader(message);
if(messageId != null) {
buffer.append(" MessageId=");
buffer.append(messageId);
}
Message inMessage = message.getExchange().getInMessage();
HttpServletRequest request = (HttpServletRequest)inMessage.get(AbstractHTTPDestination.HTTP_REQUEST);
buffer.append(" RemoteAddr=");
buffer.append(request.getRemoteAddr());
}
public Logger getLogger() {
return logger;
}
public String getName() {
return name;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
}
where MessageID is the correlation / breadcrumb id.