Difficulties sending multipart/form-data request via Postman - java

please, this is y concern: I'll like to know how to query a web service defined as in the below code using postman for test purposes.
PS: I can't change the method signature
I have a web service like this :
#POST
#Path("/uploadOpenAccountRequestFiles/{requestId}")
#Consumes({MediaType.APPLICATION_JSON,MediaType.MULTIPART_FORM_DATA})
public Response uploadOpenAccountRequestFiles(#PathParam("requestId") String requestId,
MultipartFormDataInput multipartFormDataInput)
throws JsonGenerationException, JsonMappingException, IOException {
initContext();
logger.info("DIGIBANK : uploadOpenAccountRequestFiles END: ");
String msge = "";
try {
digiBean.saveToserver(requestId, multipartFormDataInput);
} catch (Exception e) {
msge = e.getMessage();
e.printStackTrace();
}
org.af.webservice.Response resp = new org.af.webservice.Response(
request.getSession().getId(), "uploadOpenAccountRequestFiles", "",
msge.equalsIgnoreCase("OK") ? true : false, msge.equalsIgnoreCase("OK") ? false : true, "",
msge.equalsIgnoreCase("OK") ? true : false, "Boolean", msge);
logger.info("DIGIBANK : uploadOpenAccountRequestFiles END: ");
return Response.ok().entity(mapper.writeValueAsString(resp)).build();
}
this is are images of my configurations:
enter image description here
enter image description here

For calling that service, you need to pass requestId like below:
http://localhost:8080/uploadOpenAccountRequestFiles/requestId-value-here
For sending MultiPart data such as a file, you need to select form-data option in the body section in Postman and select the file by selecting the File dropdown. Also, make sure to set the appropriate headers for the request.
Check the below stackoverflow answer for more details:
Tool for sending multipart/form-data request

The steps of uploading a file through postman along with passing some input data along with the multipart request is very well discussed in below blog along with the screenshot. In this blog, the api code is written in node js. You can go through it once. It may give some information.
https://jksnu.blogspot.com/2021/09/how-to-create-post-request-with.html

Related

Why is HttpServletResponse body always empty?

My client is using the fetch api to interact with a Controller method that will decrypt a password and send the decrypted password back to the client as plain text. However, the response body never contains the password. It also continues to set the content type as basic even though I am setting it to text/plain. What am I doing wrong?
Client
function showCredentialModal(credentialId, url, username, password) {
$('#credential-id').val(credentialId ? credentialId : '');
$('#credential-url').val(url ? url : '');
$('#credential-username').val(username ? username : '');
// Display encrypted password if the current user is not the owner of the credential
if (password) {
fetch('/credentials/decrypt?credentialId=' + credentialId)
.then(response =>
console.log(response))
.catch(() =>
$('#credential-password').val('error'));
} else {
$('#credential-password').val('');
}
$('#credentialModal').modal('show');
}
Controller
#GetMapping("/decrypt")
public void doGet(HttpServletResponse response,Authentication authentication,
#ModelAttribute Credential credential) throws IOException {
User user = getCurrentUser(authentication);
credential = credentialService.getCredential(credential.getCredentialId());
boolean result = validationService.validate(credential, user);
if (result) {
String decryptedPassword = credentialService.decryptPassword(credential);
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
try (PrintWriter out = response.getWriter()) {
out.print(decryptedPassword);
out.flush();
}
}
}
Response:
Response {type: "basic", url: "http://localhost:8080/credentials/decrypt?credentialId=1", redirected: false, status: 200, ok: true, …}
body: ReadableStream
locked: false
__proto__: ReadableStream
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: ""
type: "basic"
url: "http://localhost:8080/credentials/decrypt?credentialId=1"
__proto__: Response
Your client just prints the response to console:
.then(response => console.log(response))
which shows a response with a ReadableStream body that isn't consumed:
body: ReadableStream
...
bodyUsed: false
You need to read the content of that stream to get the content the servlet returned. See for example:
Using readable streams
Body mixin
Right now you are just dumping the Response to console and its string representation isn't what you expect it to be (i.e. it's not the content but a wrapper for it). Your servlet code seems fine, it's your JavaScript client needs to be modified to read the content from within the response.
Try to debug. Actually what is wrote over very difficult to understand. Here could be some cases, but sure that "result" returns always false.
Some question for debugging:
Could method getCurrentUser() be consumed with null?
credentialId; It consumed from URL parameters that you pass in fetch method.
My suggestion to rewrite this code using samples in Spring Documentation.
Now it looks like you copied some snippets from different guides.

Python requests POST to java REST interface MultipartFile parameter is not present

I've searched around here as well as elsewhere online and can't seem to find the answer for what I think is a simple error on my part. Basically I want to transfer a file from one machine to another by issuing a Python requests.POST request to a Java REST interface on the remote machine. The Java side looks like this:
#ApiOperation(value = "Binary file transfer", nickname = "Binary file transfer")
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Success", response = HttpMessageInformationReturnDataBean.class),
#ApiResponse(code = 404, message = "Not Found")})
#RequestMapping(value = "/vm/{version}/uploadbinfile", method = RequestMethod.POST)
public String handleFileUpload(#RequestParam("binaryFile") MultipartFile file) {
if (!file.isEmpty())
{
try
{ ... the code that handles the transfer
On the Python side, the method looks like this:
def xfer_trm_binaries(self):
params = {"file": ('binaryFile',os.path.basename('TRMServer.jar')),
"folder": os.path.dirname(self.dest_temp_path),
"submit": "Submit"}
url = self.form_url("/vm/v1/uploadbinfile", self.trm_server_ip_address, self.vrm_server_port)
header=self.form_header(self.vrm_key)
header['Content-Type'] = 'multipart/file-data; boundary=randomboundarysequence'
header['enctype'] = "multipart/file-data"
print 'Send :' + url
binfile = self.local_jar_path+'TRMServer.jar'
with open(binfile, 'rb') as mfile:
try:
result = requests.post(url, headers=header,
data=params, files={'file': mfile}, verify=False)
except Exception:
The header that gets assembled there looks like this:
{'Content-Type': 'multipart/file-data; boundary=randomboundarysequence', 'Accept': 'application/json', 'Authorization': u'Bearer 8b2b6e53-9008-44b7-9d34-b5ecb9659250', 'enctype': 'multipart/file-data'}
The request is sent, however the response is always a 400 error, because it complains the MultipartFile parameter 'binaryFile' is missing:
'{"timestamp":1488597880207,"status":400,"error":"Bad Request","exception":"org.springframework.web.bind.MissingServletRequestParameterException","message":"Required MultipartFile parameter \\'binaryFile\\' is not present","path":"/vm/v1/uploadbinfile"}'
I've tried adding a 'name' value to both the params and headers of the request but it always comes back with the 400 code. Does anyone out there know what I might be doing wrong?
Actually I eventually figured this out - basically I had a method that formed the header to include the oauth bearer token, along with the ContentType and AcceptType...I then overwrote those with the multipart file info. THAT was what the receiving REST interface didn't like. When I just eliminated those header attributes altogether, it seemed to figure it out on its own.

Accessing Shoutcast Current Stream Information

i am creating an internet radio application for android. So far i have successfully streamed and played using the shoutcast url for various stations.This is my code :
String url = "http://185.33.22.13:7704";
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try
{
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
}
catch (IOException e)
{
e.printStackTrace();
}
mediaPlayer.start();
Next i would want to get the information of stream to be shown in my application.
I want to retrieve the information shown in green box:
People have posted about FFmpegMediaMetadataRetriever but github is way out of my league to understand also tried thier apk file which does nothing when given the above http link.Please suggest me a simple and robust solution to retrieve the data from SHOUTcast DNAS status.
Thanks in advance !
Shoutcast V1 has a special page with bitrate and other information.
If your shoutcast is running on
http://185.33.22.13:7704
then this page url will be:
http://185.33.22.13:7704/7.html
The body of that page looks like this:
<HTML><meta http-equiv="Pragma" content="no-cache"></head><body>214,1,312,1000,213,64,Ferry Tayle - The Way Back Home (Edit) (feat. Poppy)</body></html>
Split that text by commas and you will get:
Current listeners
Stream status
Peak listeners
Maximum number of listeners (from server start)
Unique listeners
Bitrate
Song title
Here is an example in javascript (Nodejs) that gets the data from 7.html page and parses it:
var request = require('request'),
options = {
url: 'http://185.33.22.21:7704/7.html',
headers: {
'User-Agent': 'Mozilla/5.0'
}
},
regex = /<body>(.*?)<\/body>/i;
request(options, function (error, response, body) {
var match = regex.exec(body),
data = match[1].split(',');
console.log("7.html: ", body);
console.log("Current listeners: ", data[0]);
console.log("Stream status: ", data[1]);
console.log("Peak listeners: ", data[2]);
console.log("Maximum number of listeners: ", data[3]);
console.log("Unique listeners: ", data[4]);
console.log("Bitrate: ", data[5]);
console.log("Metada: ", data[6]);
});
Please note that setting "User-Agent" header is required.
If you have admin password from that server - then another way is to get XML data directly from shoutcast admin page using the following URL:
http://185.33.22.13:7704/admin.cgi?mode=viewxml

if and else-if statements refuses to work in jquery's ajax function

I have a function that is called when a button is clicked, this function sends an ajax request using jquery. On success I have some logical if and else if statements. The web server can only send 2 types of text responses. It can either be "Success" or "Error". But when testing for these two conditions they seem to fail. I have added an else statement and an alert to tell me what the server is sending but just as I expected, it is either "Success" or "Error", the way I programmed my servlet in the server, it can only send "Success" or "Error" as response. Moreover my alert is spitting out "Success" or "Error" please I dont understand what is wrong here. please help.
function deleteRecord(productID, description)
{
var errorMessage = '<td class="red-left">There was an error. Please try again.</td>';
var successMessage = '<td class="green-left">Product '+productID+' ('+description+') has been deleted sucessfully.</td>';
var data = "productID="+productID+"&description="+description+"&deleteProduct=true";
$.ajax({
type: "GET",
url: "deleteInventoryRecord.mpcs",
data: data,
cache: false,
success: function(info)
{
if(info == 'Success')//This does not work
{
$(".green-left").replaceWith(successMessage);
$("#message-green").fadeIn("slow");
$("#product-"+productID).remove();
}
else if(info == 'Error')//This does not work
{
$(".red-left").replaceWith(errorMessage);
$("#message-red").fadeIn("slow");
}
else//This works always but I dont need it
{
alert(info); //It always says "Success" or "Error"
}
},
dataType: 'text'
});
}
Here is the servlet code that sends the response:
private void deleteProduct(HttpServletResponse response, String productID) throws IOException
{
try
{
response.setContentType("text/html");
InventoryDAO iDao = new InventoryDAO();
if(iDao.deleteProduct(productID) == true)
response.getWriter().println("Success");
else
throw new RuntimeException("Error");
}
catch(ClassNotFoundException | IOException | SQLException | RuntimeException xcp)
{
response.getWriter().println("Error");
}
}
Going to take a shot in the dark here, and say that the server is sending the response in UTF8 with a BOM, and this is causing your comparisons to fail.
To confirm, try alert(info.length). It should be 7 for "Success" or 5 for "Error". If it is not, then you probably have a BOM.
Another thing to check of course is that there is no whitespace in the response - again, the length check will help verify this.
You can fix this by encoding your server-side scripts as "UTF8 without BOM", sometimes referred to as "ANSI as UTF8" depending on your editor. Alternatively, change your if blocks to:
if( info.match(/Success$/)) ...
else if( info.match(/Error$/)) ...
Your deleteProduct method sets content type "text/html", but you are sending plain text. This is likely to confuse jQuery, as it tries to guess the type of info based on the content type header sent. Either use "text/plain", or even better "application/json", so you may sent more info to the client.

AMF client in Java

I am using BlazeDS java client to get info from this page.
This page has a form in the middle that when you select a type, the location combo on the button gets updated.
I am trying to use BlazeDS to get those values in java.
I have been using Charles web proxy to debug, and this are the screenshots from the request and the response:
My code so far is the following:
// Create the AMF connection.
AMFConnection amfConnection = new AMFConnection();
// Connect to the remote url.
String url = "http://orlandoinfo.com/flex2gateway/";
try
{
amfConnection.connect(url);
}
catch (ClientStatusException cse)
{
System.out.println(cse);
return;
}
// Make a remoting call and retrieve the result.
try
{
// amfConnection.registerAlias("flex.messaging.io.ArrayCollection", "flex.messaging.io.ArrayCollection");
amfConnection.call("ColdFusion.getLocations", new Object[] {"consumer", "attractions", "ATTR"});
}
catch (ClientStatusException cse)
{
System.out.println(cse);
}
catch (ServerStatusException sse)
{
System.out.println(sse);
}
// Close the connection.
amfConnection.close();
When I run it I get a:
ServerStatusException
data: ASObject(15401342){message=Unable to find source to invoke, rootCause=null, details=null, code=Server.Processing}
HttpResponseInfo: HttpResponseInfo
code: 200
message: OK
Can anyone spot what's wrong?
Thanks for reading!
I ended up using Charles Web Proxy. Sniffing AMF parameters and running my code with -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888
I compare both calls and modify to look alike.
The working code looks like this:
String url = "http://www.theGateWayurl.com";
// Generates the connection to the amf gateway.
AMFConnection amfConnection = new AMFConnection();
// Must register the class that this library will use to load the
// AMF object information.
// The library will read AMF object variables and use setters from
// the java bean stated in this line.
AMFConnection.registerAlias("", new LabelData().getClass().getName());
try {
// Do the connection.
amfConnection.connect(url);
// This page requires a certain headers to function.
// The Content-type is used to sniff with Charles Web Proxy.
amfConnection.addHttpRequestHeader("Content-type", "application/x-amf");
// The Referer is used by the webpage to allow gathering information.
amfConnection.addHttpRequestHeader("Referer", "http://orlandoinfo.com/ws/b2c/sitesearch/customtags/comSearch.swf");
// The rest of the HTTP POST sent by this library is wrapped
// inside a RemotingMessage.
// Prepare the msg to send.
RemotingMessage msg = new RemotingMessage();
// The method called in the server.
msg.setOperation("getLocations");
// Where the request came from. Similar to referer.
msg.setSource("ws.b2c.sitesearch.components.myService");
// The destination is a needed parameter.
msg.setDestination("ColdFusion");
// Create the body with the parameters needed to call the
// operation set with setOperation()
msg.setBody(new Object[] {"consumer", "attractions"});
// This is needed but not used.
msg.setMessageId("xxxxxxxxxx");
// Send the msg.
AcknowledgeMessage reply = (AcknowledgeMessage) amfConnection.call("null", msg);
// Parse the reply from the server.
ArrayCollection body = (ArrayCollection) reply.getBody();
for (Object obj : body) {
LabelData location = (LabelData) obj;
// Do something with the info.
}
} catch (ClientStatusException cse) {
// Do something with the exception.
} catch (ServerStatusException sse) {
// Do something with the exception.
} finally {
amfConnection.close();
}
The LabelData is just a java bean with with two vars: Data and Label.
I tried to comment every line for a better understanding.
Take into account what Stu mention in previous comments about crossdomain.xml to see if you have the rights to do this kind of things.

Categories