I have a REST service that retruns byte[]
I like to create an image (Ext.Img) which content is the service result
Service
#RequestMapping(value = "/retrieve_thumbnail", method = RequestMethod.GET)
public byte[] retrieveBDocumentThumbnail(#RequestParam String modelName,#RequestParam String modelVersion) throws BdocWebAccessException {
return service.retrieveBDocumentThumbnail(modelName, modelVersion);
}
Image
Ext.create("Ext.Img", {
src:'tablet/bDocument/retrieve_thumbnail?modelName=MODELE_INT_003_TYPES_DONNEES&modelVersion'
})
The service is invocked but I have this message in the javascript Console:
Resource interpreted as Image but transferred with MIME type text/plain: "http://localhost:8080/bdoci-tablet/tablet/bDocument/retrieve_thumbnail?modelName=MODELE_INT_003_TYPES_DONNEES&modelVersion".
I think that the problem is related to the format, How can I fix this?
The MIME type is an HTTP header that indicates what kind of file it is. In this case, it is sending text/plain. It should be indicating this is an image. I don't think your problem is on the client side, but the client is responding to an invalid response on the server side.
#RequestMapping(value = "/retrieve_thumbnail", method = RequestMethod.GET,
produces = MediaType.IMAGE_PNG_VALUE)
Related
Spring Rest Api :
#RequestMapping(value={"/save-userlist"}, method=RequestMethod.POST)
public ResponseEntity<?> saveUserList(#RequestBody UserListDTO userListDTO, #RequestBody List<User> users, #RequestParam Integer userId) {
ResponseEntity<?> response= null;
try{
logger.debug(userListDTO, );
logger.debug(users, );
return ResponseEntity.status(HttpStatus.OK).body("success");
}
catch(Exception e){
logger.debug(e.getMessage());
}
return response;
}
can anyone please suggest me how to pass multiple parameters to the Web-API from angular4
Please correct me if i'm wrong but you can only pass 1 request body. Your request body should be 1 object which contains all your variables in json format, this will automatically be serialized to i.e. the UserListDRO object.
See this example:
Method parameter user is marked with #RequestBody annotation. Thanks
to this annotation, Spring will try to bind the request body [which
can be JSON/XML/Other] to user object[ Means crating a new user object
with the details found in the request body like user name,age etc..],
based on Content-Type header in Http request.
I am using a WCF (.svc) WebService and it's working perfectly - I can call its methods without problems from Postman, PHP, etc. But, when I try to call it from JavaScript/jQuery using AJAX, there is an obvious problem - I do it from other domain than WS, so it won't let me do it.
It is all about POST methods. But there is a problem even when my page is sending firstly an OPTIONS method:
OPTIONS 'WS ADDRESS' 405 (Method Not Allowed)
XMLHttpRequest cannot load 'WS ADDRESS' Response to preflight request doesn't
pass access control check: No 'Access-Control-Allow-Origin' header is
present on the requested resource. Origin 'MY ADDRESS' is therefore not allowed
access. The response had HTTP status code 405.
There are detailed responses:
Okay, I read about cross-domain and WS's Web.config contains all of it that is necessary (?)
Please let me know what am I doing wrong that I cannot reach my WS from JavaScript, even though it seems to me configured well. But still, it seems not to send these special headers in response... Thanks in advance.
XML HttpRequest allows data to be transferred from a web server to the browser. The browsers, however, prevents CORS by default.
GET request is not going to change anything on the server side (nothing is created/updated/deleted) - it's only going to return some data.
POST/PUT/DELETE requests, however, will process the request and change something on the server side and issue a response to the browser. If the response doesn't have a proper Access-Control-Allow-Origin header, the browser will block the response. But that doesn't matter because by the time the response is issued, the server has already processed the request and made changes, perhaps to a database.
In order to prevent POST/PUT/DELETE request to be processed on server side, browsers will send a preflight request.
A prefligth request is an http request with the method OPTIONS. So before sending the POST request, the browser will send an OPTIONS request with an additional header called Access-Control-Request-Method with the value of POST.
The 405 (Method Not Allowed) error indicates the the server is not configured to accept OPTIONS request.
You can solve this issue either by using a wildcard for your web invoke method similar to this:
[OperationContract]
[WebInvoke(Method = "*", UriTemplate = "/Path", ResponseFormat = WebMessageFormat.Json)]
Or by adding an additional [OperationContract] to your [ServiceContract] that handles OPTIONS request similar to this:
[OperationContract(Name = "OptionsMyFunction")]
[WebInvoke(Method = "OPTIONS", UriTemplate = "/Path", ResponseFormat = WebMessageFormat.Json)]
You can implement .NET IDispatchMessageInspector for this work.
Create a class implementing IDispatchMessageInspector
Create a class implementing Attribute,IEndpointBehavior,IOperationBehavior
Allow only OPTIONS in your class implementing IDispatchMessageInspector
The code will look like this
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.Collections.Generic;
using System.Net;
namespace WapstyPrintService
{
public class MessageInspector : IDispatchMessageInspector
{
private ServiceEndpoint _serviceEndpoint;
Dictionary<string, string> requiredHeaders;
public MessageInspector(ServiceEndpoint serviceEndpoint)
{
_serviceEndpoint = serviceEndpoint;
requiredHeaders = new Dictionary<string, string>();
requiredHeaders.Add("Access-Control-Allow-Origin", "*");
requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
requiredHeaders.Add("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");
}
/// <summary>
/// Called when an inbound message been received
/// </summary>
/// <param name="request">The request message.</param>
/// <param name="channel">The incoming channel.</param>
/// <param name="instanceContext">The current service instance.</param>
/// <returns>
/// The object used to correlate stateMsg.
/// This object is passed back in the method.
/// </returns>
public object AfterReceiveRequest(ref Message request,
IClientChannel channel,
InstanceContext instanceContext)
{
var httpRequest = (HttpRequestMessageProperty)request
.Properties[HttpRequestMessageProperty.Name];
return new
{
origin = httpRequest.Headers["Origin"],
handlePreflight = httpRequest.Method.Equals("OPTIONS",
StringComparison.InvariantCultureIgnoreCase)
};
}
/// <summary>
/// Called after the operation has returned but before the reply message
/// is sent.
/// </summary>
/// <param name="reply">The reply message. This value is null if the
/// operation is one way.</param>
/// <param name="correlationState">The correlation object returned from
/// the method.</param>
public void BeforeSendReply(ref Message reply, object correlationState)
{
var state = (dynamic)correlationState;
if (state.handlePreflight)
{
reply = Message.CreateMessage(MessageVersion.None, "PreflightReturn");
var httpResponse = new HttpResponseMessageProperty();
reply.Properties.Add(HttpResponseMessageProperty.Name, httpResponse);
httpResponse.SuppressEntityBody = true;
httpResponse.StatusCode = HttpStatusCode.OK;
}
var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
foreach (var item in requiredHeaders)
{
httpHeader.Headers.Add(item.Key, item.Value);
}
}
}
}
and
using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace WapstyPrintService
{
public class BehaviorAttribute : Attribute, IEndpointBehavior,
IOperationBehavior
{
public void Validate(ServiceEndpoint endpoint) { }
public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters)
{ }
/// <summary>
/// This service modify or extend the service across an endpoint.
/// </summary>
/// <param name="endpoint">The endpoint that exposes the contract.</param>
/// <param name="endpointDispatcher">The endpoint dispatcher to be
/// modified or extended.</param>
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher)
{
// add inspector which detects cross origin requests
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
new MessageInspector(endpoint));
}
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{ }
public void Validate(OperationDescription operationDescription) { }
public void ApplyDispatchBehavior(OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{ }
public void ApplyClientBehavior(OperationDescription operationDescription,
ClientOperation clientOperation)
{ }
public void AddBindingParameters(OperationDescription operationDescription,
BindingParameterCollection bindingParameters)
{ }
}
}
Then add your message inspector to service endpoint behavior
ServiceHost host = new ServiceHost(typeof(myService), _baseAddress);
foreach (ServiceEndpoint EP in host.Description.Endpoints)
EP.Behaviors.Add(new BehaviorAttribute());
I know how to send a post request with angular to an API, but was wondering how to retrieve post request sent from an application.
Let say I have this C# post request:
public string sendPost(string data)
{
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("http://localhost:5000/app/edit");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "{\"data\":\"" + data + "\"}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/json";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
return responseFromServer;
}
In my angular app I have this controller:
(function () {
'use strict';
angular.module('anbud')
.controller('editController', ['$scope', 'localStorage', 'md5', '$routeParams', 'httpError',
function ($scope, localStorage, md5, $routeParams, httpError) {
function processHeaderData() {
console.log($routeParams.json);
}
processHeaderData();
}]);
}());
I can send data via a the url and use routeParams, but I would like to use POST instead. How do I access the POST data?
I think you are mixing up front end and web server technologies.
Angular is a front end technology, what you mean sending a post to angular, actually means sending a request to the web server that hosts the angular website.
Once you make this clear, you just need to send an API call to the web server like how you do with angular, and the server will return the json data you need.
If you want to get the HTML representation of particular route, I'm afraid there is no good way to achieve this. This is not particular with angular either, any site that loads data with ajax call would have this problem.
Angular $http.post can also retrieve data. For security purposes, this is quite beneficial. Logic for that remains the same.
You could send data from your c# controller through this:
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace Sample.API.Controllers
{
public class ContentDataController
{
[Route("api/ContentData")]
[HttpPost]
public HttpResponseMessage SamplePost(SampleRequest request)
{
HttpResponseMessage response;
try
{
var cda = dataContentAdapter();
//Business logic here
var result = cda.GetContent(request);
//pass the above result to angular
response = Request.CreateResponse(HttpStatusCode.OK, result);
response.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(300));
}
catch (Exception ex)
{
ApplicationLogger.LogCompleteException(ex, "ContentDataController", "Post");
HttpError myCustomError = new HttpError(ex.Message) { { "IsSuccess", false } };
return Request.CreateErrorResponse(HttpStatusCode.OK, myCustomError);
}
return response;
}
}
}
With this, send a request from angular with whatever data that needs to be used in request. Favorable is to send json, parse the json in your business logic.
Create a HttpResponseMessage with the new payload for angular $http to recieve.
I'm searching to send a zip file to a server using the "Request" class from the new Firefox SDK for addons. This is my code:
var Request = require("sdk/request").Request;
var file = new FileUtils.File(pathToZipFile);
Request({
url: serverURL,
content: file,
onComplete: function (response) {
for (var headerName in response.headers) {
console.log(headerName + " : " + response.headers[headerName]);
}
console.log("Response " + response.text );
}
}).post();
But the error is:
[Exception... "Component returned failure code: 0x80520009 (NS_ERROR_FILE_INVALID_PATH) [nsILocalFile.target]" nsresult: "0x80520009 (NS_ERROR_FILE_INVALID_PATH)" location: "JS frame :: resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/querystring.js :: stringify/< :: line 70" data: no]
I have tried to do some checks and:
The server is on and receives normal GET and POST without files
The zip file is present and the path is right
Do you see any errors?
Thanks a lot
The only way to do it with the Request module is to base a base64 encoded string to the content key. If you don't use this, then you can send data such as a Blob or DOMFile (new File()) instance.
But as we see in the SDK code, the request module sends the data variable on request (if its not a HEAD or GET request).
https://github.com/mozilla/addon-sdk/blob/master/lib/sdk/request.js#L110
The data var is made by running stringify on anything passed to the content key:
https://github.com/mozilla/addon-sdk/blob/master/lib/sdk/request.js#L76
Stringify makes it a string:
https://github.com/mozilla/addon-sdk/blob/f5fab7b242121dccfa4e55ac80489899bb9f2a41/lib/sdk/querystring.js#L30
So you have to send base64 encoded string. Or a binary string. Which sucks.
You can use the sdk/io module to read the file as an ArrayBuffer and then turn that ArrayBuffer into a base64 string or binary string.
This shows how to get a binary string: https://stackoverflow.com/a/16365505/1828637
I need help. I have single html-file running on my webserver. Via Javascript I'm sending data to my Java-Servlet on the same server via xhttp-request.
On Java's servlet side I can send a message back to the xhttp-request via a PrintWriter like below:
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
PrintWriter theMessenger = response.getWriter();
theMessenger.print("Response data");
}
That all works fine. But now I need to send a message to the requesting html-file without the use of the servlet-response.
Are there any possibilities for sending data (strings as usual) to the html-file gathering those messages via onmessage-handler for example?
I tried this, but the messange never reaches it target:
String targetURL = CSConfig.GetRootURL() + "/myRequestingPage.html";
URL objUrl = new URL(targetURL);
HttpURLConnection urlCon = (HttpURLConnection) objUrl.openConnection();
urlCon.setRequestMethod("POST");
urlCon.setDoOutput(true);
DataOutputStream dataWriter = new DataOutputStream(urlCon.getOutputStream());
dataWriter.writeBytes(messageContent);
dataWriter.flush();
dataWriter.close();