I have been working on Gzipping the response, but its work's fine in nodejs, but the same code is not working in java platform. After digging further i found that the key isBase64Encoded : true is not correctly been identified in the client( Chrome browser specifically)
public class ExampleHandler1 implements RequestHandler<AwsProxyRequest,AwsProxyResponse> {
#Override
public AwsProxyResponse handleRequest(AwsProxyRequest input, Context context) {
AwsProxyResponse response = new AwsProxyResponse(200, Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless"), "Aaytu");
try {
HashMap<String, String> headermap = new HashMap<>();
headermap.put("Content-Encoding", "gzip");
headermap.put("Content-Type", "text/html");
String responseString = Base64.getMimeEncoder().encodeToString(GzipCompressor.compress("Hello there..!!!").getBytes());
AwsProxyResponse retVal = new AwsProxyResponse(200, headermap, responseString);
retVal.setBase64Encoded(true);
return retVal;
} catch (Exception e) {
}
return response;
}
}
Related
We are migrating to Redis from RabbitMQ in our microservice applications.
Here is our service activator
#ServiceActivator(inputChannel = ApplicationEventChannelNames.REMOTE_CHANNEL)
public void handleApplicationEvent(#Header(value = ApplicationEventHeaders.APPLICATION_EVENT) final ApplicationEvent event,
#Payload Object message) {
...
}
Initially we had a problem where we were losing application event in the SimpleMessageConverter. We solved it by implementing a CustomRedisMessageConverter and putting application event into the payload in the fromMessage method and retreiving it from payload and create a new message headers with application event in the toMessage method.
#Override
public Object fromMessage(Message<?> message, Class<?> targetClass) {
if (message.getHeaders().get(ApplicationEventHeaders.APPLICATION_EVENT) != null) {
Map<String, Object> map = new HashMap<>();
map.put("headers", ((ApplicationEvent) message.getHeaders().get(ApplicationEventHeaders.APPLICATION_EVENT)).getName());
map.put("payload", message.getPayload());
GenericMessage<Map<String, Object>> msg = new GenericMessage<>(map, message.getHeaders());
return super.fromMessage(msg, targetClass);
}
return super.fromMessage(message, targetClass);
}
#Override
public Message<?> toMessage(Object payload, MessageHeaders headers) {
try {
final Map<String, ?> message = new ObjectMapper().readValue((String) payload, new TypeReference<Map<String, ?>>() {});
if (message.get("headers") != null) {
final Map<String, Object> messageHeaders = new HashMap<>(headers);
messageHeaders.put(ApplicationEventHeaders.APPLICATION_EVENT, new ApplicationEvent((String) message.get("headers")));
return super.toMessage(message.get("payload"), new MessageHeaders(messageHeaders));
}
} catch (JsonProcessingException exception) {
/* Intentionally left blank */
}
return super.toMessage(payload, headers);
}
We are wondering if there is a better approach for doing this?
Lastly, payload in the service activator come as a LinkedHashMap but we want it to be an object. With RabbitMQ this was handled.
Is there any way to do the same in Redis? Or do we use headers to keep track of the type of a payload and manually convert them into an object?
UPDATE - REDIS Configuration
#Bean
public RedisInboundChannelAdapter applicationEventInboundChannelAdapter(#Value(value = "${com.xxx.xxx.xxx.integration.spring.topic}") String topic,
MessageChannel applicationEventRemoteChannel,
RedisConnectionFactory connectionFactory) {
final RedisInboundChannelAdapter inboundChannelAdapter = new RedisInboundChannelAdapter(connectionFactory);
inboundChannelAdapter.setTopics(topic);
inboundChannelAdapter.setOutputChannel(applicationEventRemoteChannel);
inboundChannelAdapter.setErrorChannel(errorChannel());
inboundChannelAdapter.setMessageConverter(new CustomRedisMessageConverter());
return inboundChannelAdapter;
}
#ServiceActivator(inputChannel = "errorChannel")
public void processError(MessageHandlingException exception) {
try {
logger.error(
"Could not process {}, got exception: {}",
exception.getFailedMessage().getPayload(),
exception.getMessage());
logger.error(
ExceptionUtils.readStackTrace(exception));
} catch (Throwable throwable) {
logger.error(
"Got {} during processing with message: {} ",
MessageHandlingException.class.getSimpleName(),
exception);
}
}
#Bean
#ServiceActivator(inputChannel = ApplicationEventChannelNames.LOCAL_CHANNEL)
public RedisPublishingMessageHandler redisPublishingMessageHandler(#Value(value = "${com.xxx.xxx.xxx.integration.spring.topic}") String topic,
RedisConnectionFactory redisConnectionFactory) {
final RedisPublishingMessageHandler redisPublishingMessageHandler = new RedisPublishingMessageHandler(redisConnectionFactory);
redisPublishingMessageHandler.setTopic(topic);
redisPublishingMessageHandler.setSerializer(new Jackson2JsonRedisSerializer<>(String.class));
redisPublishingMessageHandler.setMessageConverter(new CusomRedisMessageConverter());
return redisPublishingMessageHandler;
}
/*
* MessageChannel
*/
#Bean
public MessageChannel errorChannel() {
return new DirectChannel();
}
Redis does not support headers, so you have to embed them into a body. See EmbeddedJsonHeadersMessageMapper which could be supplied into that org.springframework.integration.support.converter.SimpleMessageConverter on both side.
I am not getting virtually any response.
This is for a school project, i am not getting any response from volley what so ever, please help.
I've tried different versions of Volley, I've tried adding internet access to the manifest, no help.
RequestQueue queue = Volley.newRequestQueue(this);
api();
public void api(){
String new_url = "http://api.myjson.com/bins/kp9wz";
System.out.println(new_url);
final JsonObjectRequest request = new
JsonObjectRequest(Request.Method.GET, new_url, null, new
Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("employees");
devices = new ArrayList<>();
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String deviceId = jsonObject.getString("firstname");
String deviceName = jsonObject.getString("age");
String deviceStatus = jsonObject.getString("mail");
System.out.println(jsonObject.getString("firstname"));
System.out.println(jsonObject.getString("age"));
System.out.println(jsonObject.getString("mail"));
devices.add(new
Device(deviceName,deviceStatus,deviceId));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
System.out.println("WTF");
}
});
}
ยดยดยด
I don't get anything
I expect it to save the data into the arraylist and sout, each field in the for loop
I was stupid enough to not att the request to a RequestQueue, I've solved it.
I'm using retrofit to upload images on server, image are uploading successfully, but without extension.
Means only image name is uploading to database, extension is not there.
So image became useless for me.
please provide help.
here is my method in interface->
#FormUrlEncoded
#POST("/webservices/AssessorAssetsUpload.php")
Call<ImageModel> uploadImage(
#Field("name")String pictype,
#Field("type")String uploadtype,
#Field("accesser_id")String asses_id,
#Field("paper_schedule_id")String paper_id,
#Field("imagefile")String image
);
my activity code->
String image=imagetoString();
RetrofitInterface retrofit=ApiClient.getApiClient().create(RetrofitInterface.class);
Call<ImageModel> call=retrofit.uploadImage(imageName,"image",assessor_id,paperId,image);
call.enqueue(new Callback<ImageModel>() {
#Override
public void onResponse(Call<ImageModel> call, Response<ImageModel> response) {
System.out.println(response.body().getStatus()+" "+response.body().getMsg()+" "+response.body().getUrl());
}
#Override
public void onFailure(Call<ImageModel> call, Throwable t) {
t.printStackTrace();
}
});
}
private String imagetoString(){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
byte[] bytes=stream.toByteArray();
return Base64.encodeToString(bytes,Base64.DEFAULT);
}
We use Multipart instead of formurlencoded in case of any multimedia object.
#Multipart
#POST("/webservices/AssessorAssetsUpload.php")
Call<ImageModel> uploadImage(
#Part("name")RequestBody pictype,
#Part("type")RequestBody uploadtype,
#Part("accesser_id")RequestBody asses_id,
#Part("paper_schedule_id")RequestBody paper_id,
#Part("imagefile")MultipartBody.Part image
);
MultipartBody.Part image=imagetoPart();
RetrofitInterface retrofit=ApiClient.getApiClient().create(RetrofitInterface.class);
Call<ImageModel> call=retrofit.uploadImage(
getTextRequest("imageName"),
getTextRequest("image"),
getTextRequest("assessor_id"),
getTextRequest("paperId"),
image
);
call.enqueue(new Callback<ImageModel>() {
#Override
public void onResponse(Call<ImageModel> call, Response<ImageModel> response) {
System.out.println(response.body().getStatus()+" "+response.body().getMsg()+" "+response.body().getUrl());
}
#Override
public void onFailure(Call<ImageModel> call, Throwable t) {
t.printStackTrace();
}
});
}
private String imagetoPart(){
Bitmap bitmap = BitmapFactory.decodeFile("Image Path");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
byte[] bytes=stream.toByteArray();
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), bytes);
MultipartBody.Part part = MultipartBody.Part.createFormData("name", "name", reqFile);
return part;
}
private RequestBody getTextRequest(String body) {
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), body);
return requestBody;
}
We need to convert the fields into request body and image into a multipart body to send it as a multipart request. This will do your work.
I need help with creating a windows service using Threading and asynchronous HttpWebRequest calls. I have created a few C# windows services before but never using threading. Also, I seem to be getting hung up with the async calls using HttpWebRequest. I have googled this as well as looking on this site. I could not find anything that helped. This is mainly because I could not seem to get what was presented in other questions to work in my specific example.
Please keep in mind that I may be overlapping things based on my lack of knowledge in this specific area as well as through trying to figure it out.
The main flow of this is to get a list of urls during onStart. Typically this list would be retrieved from a _facade.GetUrls call. Then, at each time interval call scanSites. A request is made to each url and then I save the results to the database in _facade.SaveUrlResponse.
My problems is it seems as if I am caught in an endless loop when I debug it. I am not exactly sure how/where to do this. Thanks in advance.
Here is what I have:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.ServiceProcess;
using System.Threading;
using URLValidation.BusinessManager.Facade;
using URLValidation.BusinessManager.Model;
namespace URLValidation
{
partial class URLValidation : ServiceBase
{
#region " class variables "
private System.Timers.Timer _timer;
private List<UrlModel> _url_List = null;
private Facade _facade;
private Thread _t;
private int _x;
#endregion
public URLValidation()
{
_facade = new Facade();
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
_url_List = new List<UrlModel>
{
new UrlModel(address: "http://www.google.com", addressID: 1),
new UrlModel(address: "http://www.microsoft.com", addressID: 2),
new UrlModel(address: "http://www.stackoverflow.com", addressID: 3)
};
resetTimer();
GC.KeepAlive(_timer);
}
catch (Exception ex)
{
throw ex;
}
}
private void resetTimer()
{
try
{
_timer = new System.Timers.Timer();
_timer.Interval = 10000;//1800000; //30 minutes
_timer.Start();
_timer.Enabled = true;
_timer.Elapsed += scanSites;
}
catch (Exception ex)
{
throw ex;
}
}
private void scanSites(object sender, System.Timers.ElapsedEventArgs e)
{
_timer.Stop();
_x = 0;
_t = new Thread(new ThreadStart(scanSites));
_t.IsBackground = true;
_t.Start();
}
private void scanSites()
{
try
{
foreach (UrlModel url in _url_List)
{
_x += 1;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url.Address);
request.Method = "HEAD";
RequestModel requestModel = new RequestModel(request, url);
IAsyncResult result = request.BeginGetResponse(new AsyncCallback(saveUrlResponse), requestModel);
ThreadPool.RegisterWaitForSingleObject
(
result.AsyncWaitHandle,
new WaitOrTimerCallback(ScanTimeoutCallback),
requestModel,
(30 * 1000), // 30 second timeout
true
);
}
}
catch (Exception ex)
{
throw ex;
}
}
private void saveUrlResponse(IAsyncResult result)
{
//grab the custom state object
RequestModel requestModel = (RequestModel)result.AsyncState;
HttpWebRequest request = (HttpWebRequest)requestModel.Request;
//get the Response
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
// process the response...
ResponseModel responseModel = new ResponseModel(request, response, requestModel.UrlModel.AddressID);
_facade.SaveUrlResponse(responseModel);
}
private void ScanTimeoutCallback(object requestModel, bool timedOut)
{
if (timedOut)
{
RequestModel reqState = (RequestModel)requestModel;
if (reqState != null)
reqState.Request.Abort();
}
if (_x == _url_List.Count)
{
resetTimer();
}
}
protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to stop your service.
}
}
}
Okay, I think I am getting somewhere. I have moved my code to a console app. I am able to get the results saved to the database by using either GetResponse (sync) and BeginGetResponse (async). From what I can tell I believe this is a good solution. Can somebody verify this and let me know if you foresee any problems once this is moved to a Windows Service. Here is the new code
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
namespace ConsoleApplication2
{
static class Program
{
private static List<UrlModel> _url_List = null;
private static Object _acctLock = new object();
private static Facade _facade = new Facade();
static void Main(string[] args)
{
_url_List = new List<UrlModel>
{
new UrlModel(address: "http://www.microsoft.com", addressID: 1),
new UrlModel(address: "http://www.google.com", addressID: 2),
new UrlModel(address: "http://www.stackoverflow.com", addressID: 3)
};
lockThreadAndGetUrlStatus(_url_List);
Console.ReadLine();
}
static void lockThreadAndGetUrlStatus(List<UrlModel> _url_List)
{
Thread[] threads;
try
{
threads = new Thread[_url_List.Count];
Thread.CurrentThread.Name = "main";
int i = 0;
foreach (UrlModel url in _url_List)
{
//Thread t = new Thread(() => scanSites(url));
Thread t = new Thread(() => scanSitesWithAsync(url));
t.Name = i.ToString();
threads[i] = t;
i += 1;
}
for (i = 0; i < _url_List.Count; i++)
{
Console.WriteLine("Thread {0} Alive : {1}", threads[i].Name, threads[i].IsAlive);
threads[i].Start();
Console.WriteLine("Thread {0} Alive : {1}", threads[i].Name, threads[i].IsAlive);
}
Console.WriteLine("Current Priority : {0}", Thread.CurrentThread.Priority);
Console.WriteLine("Thread {0} Ending", Thread.CurrentThread.Name);
}
catch (Exception ex)
{
throw ex;
}
}
static void scanSitesWithAsync(UrlModel url)
{
try
{
lock (_acctLock)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url.Address);
request.Method = "HEAD";
RequestModel requestModel = new RequestModel(request, url);
IAsyncResult result = request.BeginGetResponse(new AsyncCallback(saveUrlResponseWithAsync), requestModel);
ThreadPool.RegisterWaitForSingleObject
(
result.AsyncWaitHandle,
new WaitOrTimerCallback(scanTimeoutCallback),
requestModel, 30000, true
);
}
}
catch (Exception ex)
{
throw ex;
}
}
static void saveUrlResponseWithAsync(IAsyncResult result)
{
try
{
RequestModel requestModel = (RequestModel)result.AsyncState;
HttpWebRequest request = (HttpWebRequest)requestModel.Request;
//get the Response
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
// process the response...
ResponseModel responseModel = new ResponseModel(requestModel.Request, response, requestModel.UrlModel.AddressID);
_facade.SaveUrlResponse(responseModel);
Console.WriteLine(response.StatusCode);
}
catch (Exception ex)
{
throw ex;
}
}
static void scanTimeoutCallback(object requestModel, bool timedOut)
{
try
{
if (timedOut)
{
RequestModel reqState = (RequestModel)requestModel;
if (reqState != null)
reqState.Request.Abort();
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}
looks like you are trying to issue 3 async requests at the same time. By default, the HTTP/1.1 protocol only specifies 2 connections
Trying to fetch the response using spring web client, but the result response is getting truncated as the response size is more than that of string class. Is there any other way to get the response without being truncated?
LinkedMultiValueMap<String, Object> requestMap = new LinkedMultiValueMap<String, Object>();
//String response = "";
try{
File tempFile = File.createTempFile("ccda", "File");
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(ccdaFile.getInputStream(), out);
requestMap.add("ccdaFile", new FileSystemResource(tempFile));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity =
new HttpEntity<LinkedMultiValueMap<String, Object>>(requestMap, headers);
RestTemplate restTemplate = new RestTemplate();
FormHttpMessageConverter formConverter = new FormHttpMessageConverter();
formConverter.setCharset(Charset.forName("UTF8"));
restTemplate.getMessageConverters().add(formConverter);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
String response = restTemplate.postForObject("localhost:8080",
requestEntity, String.class);
tempFile.delete();
}catch(Exception exc)
{
exc.printStackTrace();
}
You may use an InputStream
I think you may do in this way:
InputStream is = rt.execute("localhost:8080", HttpMethod.POST, requestCallback, responseExtractor);
Where requestCallback is an implementation of org.springframework.web.client.RequestCallback like this one
public class MyRequestCallback implements RequestCallback
{
#Override
public void doWithRequest(ClientHttpRequest request) throws IOException
{
request.getHeaders().add(HttpHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON_VALUE);
request.getHeaders().add(HttpHeaders.ACCEPT, MimeTypeUtils.APPLICATION_JSON_VALUE);
}
}
While responseExtractor may by an instance of this class
public class MyResponseExtractor implements ResponseExtractor<InputStream>
{
#Override
public Boolean extractData(ClientHttpResponse response) throws IOException
{
HttpStatus status = response.getStatusCode();
switch (status)
{
case OK:
return response.getBody();
default:
return null;
}
}
}
Once obtained the InputStream you can manage it
Hope it is usefull