Dear Stackoverflow users,
I have been playing around with restful webservice for quite a while now.
I have a small doubt in how to pass a parameter using GET method.
As get can only be used to retrieve any resources, how is it possible to pass parameter.
I have written a small code for this, but there seem to be something wrong with the code.
#GET
#Produces("text/plain")
#Path("/instrumentname/")
public String getname(String name1) {
try {
String [] env=null;
String[]callAndArgs= {"python","connection.py",ins_name};//passing the parameters
Process p = Runtime.getRuntime().exec(callAndArgs,env,
new java.io.File("C:\\Users\\Balkishore\\Documents\\NetBeansProjects\\Testinstrument_Rest\\build\\web"));//excuting the python file
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));//getting the input
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));//getting the error
interface_name = stdInput.readLine();//reading the output
System.out.println(interface_name);
}
catch (IOException e) {//catching the exception
System.out.println("exception occured");
e.printStackTrace();
System.exit(-1);
}
return this.interface_name;
}
Any help would be very much appreciated.
Thanks a ton in advance.
Cheers!
you just need to concatenate parameters at the end of the URL in following format:
www.xyz.com/?param1=val1¶m2=val2¶m3=val3
where param1, param2 are parameter names and val1,val2 are values for the corresponding parameters... You can just type them in a browser's URL bar instead of writing an HTML page or a script for testing...
Also, you are right in saying that GET is Generally used to fetch resources from a web server, but at times you have to pass information whose resource has to be fetched...
Related
Epicor ERP 10.2.500 has been recently released with the addition of Epicor Functions. They can be called from within Method and Data Directives.
Do anybody has been able to do so with a Form Customization within Epicor?
This is possible via a REST call to your function API. In this case, I had a function that sent an email from some inputs.
private void epiButtonC1_Click(object sender, System.EventArgs args)
{
//API Key is included in the query param in this example.
var request = (HttpWebRequest)WebRequest.Create("https://{appserver}/{EpicorInstance}/api/v2/efx/{CompanyID}/{LibraryID}/{functionName}/?api-key={yourAPIKey}");
request.Method = "POST";
//All REST v2 requests also sent with authentication method (Token, Basic)
//This should be Base64 encoded
string username = "userName";
string password = "passWord";
string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
request.Headers.Add("Authorization", "Basic " + encoded);
//Add body to correspond to request signature
request.ContentType = "application/json";
using(var writer = new StreamWriter(request.GetRequestStream()))
{
var values = new Dictionary<string, string>;
{
{"toEmailAddress", "someEmail#email.com"},
{"fromEmailAddress","someOtherEmail#email.com"},
{"body","This is the body"},
{"subject","Hello from Client Code!"}
};
string json = JsonConvert.SerializeObject(values);
writer.Write(json);
}
using (var response = request.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
{
var result = reader.ReadToEnd();
epiTextBoxC1.Text = result.ToString();
}
}
Haven't done it myself personally, but looking into the first post release notes about it here leads me to believe there is no out of the box solution, yet in this version/initial release.
However I'm sure you could do a HTTP request from within the Epicor customization if you have the REST API enabled in your environment.
If you create your own dll that calls the EpicorFunction you can use it within the customization. Still looking for a way to call them directly.
REST endpoint is the recommended way to perform the function call as pointed out by a-moreng.
If for some reason you cannot use this, you can use a passthrough method to any server-side BO via a customization Adapter. For instance, create an updatable BAQ which you can call from a customization using the DynamicQueryAdapter.
Pick an arbitrary table and field to save the BAQ.
Create three string parameters to store the Function library name, the function name, and a delimited list of parameters.
On the GetList method, create a Base Processing Directive.
Split your delimited parameter list and convert them to the appropriate datatypes.
Use the resulting variables to call your function.
If desired, you can pass return variables into the ttResults of the BAQ
I made a test JWT using something like the following code
String jwt = Jwts.builder()
.setHeaderParam("typ", "jwt")
.setId("myid")
.setIssuer("ExampleIssuer")
.setSubject("JohnDoe")
.setIssuedAt(Date.from(LocalDateTime.now().toInstant(ZoneOffset.ofHours(-4))))
.setExpiration(Date.from(LocalDateTime.now().toInstant(ZoneOffset.ofHours(-4)).plusSeconds(600)))
.claim("perms",perms)
.signWith(SignatureAlgorithm.HS512, "SECRET")
.compact();
"perms" is a custom claim, which contains an ArrayList of Strings (permissions).
So when I receive the JWT back, I use the following code
try{
Jwt<?, ?> claims = Jwts.parser().setSigningKey("SECRET").parse(jwt);
System.out.println(claims.getBody().toString());
} catch (SignatureException e){
//Error
}
And I get something like
{jti=myid, iss=ExampleIssuer, sub=JohnDoe, iat=1495678299, exp=1495678899, perms=[CREATE, VIEW]}
My question is: is this the correct (intended) way to get the claims back? It seems from now I will need to parse the result with a custom method, but I think somehow that is not the intended way.
Thank you.`
I found a solution, not sure if the intended one, but it works. I need to use
Claims claims = new DefaultClaims();
try{
claims = Jwts.parser().setSigningKey("SECRET").parseClaimsJws(jwt).getBody();
} catch (SignatureException e){
//Signature error
}
I can use Map methods on claims, but also the built-in methods to recover the individual claims:
String jti = claims.getId();
String iss = claims.getIssuer();
String sub = claims.getSubject();
String iat = claims.getIssuedAt().toString();
String exp = claims.getExpiration().toString();
#SuppressWarnings("unchecked")
ArrayList<String> perms = (ArrayList<String>) claims.get("perms");
I think I can suppress the warning on the unchecked casting because since I created the custom claim with the same value class, I know what to expect on it. Now the claims in the token are parsed correctly into variables I can work with.
first I have to say, that I am pretty new to Springs RestTemplate.
I am trying to receive data from the imdb-api. (For example http://imdbapi.org/?title=Avatar&type=xml) Therefore I am using Springs RestTemplate.
But:
the webservice returns the data as application/octet-stream (even I declared that I want it as xml (when I browse the site with my browser I get the data as text/xml))
RestTemplate doesn't find my declared ByteArrayMessageConverter (to convert application/octet-stream)
I realy don't know where my mistakes are.
Here is the code to initialise the restTemplate:
public void onInit() {
_log.debug("Setting up the Spring Resttemplate");
_restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
list.add(new SourceHttpMessageConverter<Source>());
list.add(new ByteArrayHttpMessageConverter());
_restTemplate.setMessageConverters(list);
_log.debug("Setting up the HTTP Headers for Restrequest");
List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
_log.trace("allow {}", MediaType.APPLICATION_XML_VALUE);
acceptableMediaTypes.add(MediaType.APPLICATION_XML);
_log.trace("allow {}", MediaType.TEXT_HTML_VALUE);
acceptableMediaTypes.add(MediaType.TEXT_XML);
_log.trace("set accepted charset to uft-8");
List<Charset> acceptableCharsets = new ArrayList<Charset>();
acceptableCharsets.add(Charset.forName("utf-8"));
_httpHeaders = new HttpHeaders();
_httpHeaders.set("User-Agent", "something"); //only a user-agent, because the api returns a 403 if it is not set
_httpHeaders.setAcceptCharset(acceptableCharsets);
_httpHeaders.setAccept(acceptableMediaTypes);
}
Here is the code with the call:
_log.info("connect to Imdb-Webservice {}", _imbdWebserviceBaseUrl);
Map<String, Object> uriVariables = new HashMap<String, Object>();
uriVariables.put("title", pTitle);
ResponseEntity<Source> response = _restTemplate.exchange(_imbdWebserviceBaseUrl, HttpMethod.GET, new HttpEntity<String>(_httpHeaders), Source.class, uriVariables);
_imbdWebserviceBaseUrl is set to http://imdbapi.org/?title={title}&type=xml
Then I am getting this error message:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface javax.xml.transform.Source] and content type [application/octet-stream]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:107)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:687)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:673)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:491)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:454)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:401)
at my.domain.projectname.integrationimpl.WebserviceHelper.getXml(WebserviceHelper.java:131)
Thanks for your help
the web service returns the data as application/octet-stream (even I declared that I want it as xml (when I browse the site with my browser I get the data as text/xml))
As far as I can see this rest service is not giving back the correct Content-Type (text/xml or similar). If your browser renders it correctly that's probably Chrome or Firefox, but IE will just show you html-ish kind of output.
RestTemplate doesn't find my declared ByteArrayMessageConverter (to convert application/octet-stream)
Well you are asking for a Source as far as I can see:
ResponseEntity<Source> response = _restTemplate.exchange(_imbdWebserviceBaseUrl, HttpMethod.GET, new HttpEntity<String>(_httpHeaders), Source.class, uriVariables);
The MessageConverters themselves have a method that determines if this converter is applicable, for ByteArrayHttpMessageConverter this is:
#Override
public boolean supports(Class<?> clazz) {
return byte[].class.equals(clazz);
}
Since you are asking for a Source.class it wont use this converter.
I need to be able to send an email from a silverlight client-side application.
I've got this working by implementing a webservice which is consumed by the application.
The problem is that now I need to be able to add an attachment to the emails that are being sent.
I have read various posts, tried a dozen times to figure it out by myself, but to no prevail.
So now I find myself wondering if this is even possible?
The main issue is that the collection of attachments needs to be serializable. So, going by this, ObservableCollection - of type(FileInfo) is not working, ObservableCollection - of type (object) is not working... I've tried using List - of type(Stream), which serializes, but then i do not know how to create the file on the webservice side, as the stream-object does not have a name (which is the first thing I tried to assign to the Attachment object which will then be added to the message.attachments)... I'm kind of stuck in a rut here.
Can anybody maybe shed some light on this please?
I figured out how to do this, and it wasn't really as difficult as it appeared.
Create the following in your webservice-namespace:
`
[Serializable]
public class MyAttachment
{
[DataMember]
public string Name { get; set; }
[DataMember]
public byte[] Bytes { get; set; }
}`
Then add the following to your web-method parameters:
MyAttachment[] attachment
Add the following in the execution blocks of your web-method:`
foreach (var item in attachment)
{
Stream attachmentStream = new MemoryStream(item.Bytes);
Attachment at = new Attachment(attachmentStream, item.Name);
msg.Attachments.Add(at);
}`
Create the following property (or something similar) at your client-side:
`
private ObservableCollection<ServiceProxy.MyAttachment> _attachmentCollection;
public ObservableCollection<ServiceProxy.MyAttachment> AttachmentCollection
{
get { return _attachmentCollection; }
set { _attachmentCollection = value; NotifyOfPropertyChange(() => AttachmentCollection); }
}`
New up the public property (AttachmentCollection) in the constructor.
Add the following where your OpenFileDialog is supposed to return files:`
if (openFileDialog.File != null)
{
foreach (FileInfo fi in openFileDialog.Files)
{
var tempItem = new ServiceProxy.MyAttachment();
tempItem.Name = fi.Name;
var source = fi.OpenRead();
byte[] byteArray = new byte[source.Length];
fi.OpenRead().Read(byteArray, 0, (int)source.Length);
tempItem.Bytes = byteArray;
source.Close();
AttachmentCollection.Add(tempItem);
}
}`
Then finally where you call your web-method to send the email, add the following (or something similar):
MailSvr.SendMailAsync(FromAddress, ToAddress, Subject, MessageBody, AttachmentCollection);
This works for me, the attachment is sent with the mail, with all of its data exactly like the original file.
I create a simple silverlight 4.0 application used to read the excel file data in the share point 2010 server. I try to use the "Excel Web Services" but I get an error here when calling the GetRangeA1 method:
An unhandled exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in mscorlib.dll
Additional information: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://schemas.microsoft.com/office/excel/server/webservices:GetRangeA1Response. The InnerException message was 'Error in line 1 position 361. Element 'http://schemas.microsoft.com/office/excel/server/webservices:anyType' contains data from a type that maps to the name 'http://schemas.microsoft.com/office/excel/server/webservices:ArrayOfAnyType'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'ArrayOfAnyType' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
the source code is like:
namespace SampleApplication
{
class Program
{
static void Main(string[] args)
{
ExcelServiceSoapClient xlservice = new ExcelServiceSoapClient();
xlservice.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
Status[] outStatus;
string targetWorkbookPath = "http://phc/Shared%20Documents/sample.xlsx";
try
{
// Call open workbook, and point to the trusted location of the workbook to open.
string sessionId = xlservice.OpenWorkbook(targetWorkbookPath, "en-US", "en-US", out outStatus);
Console.WriteLine("sessionID : {0}", sessionId);
//1. works fines.
object res = xlservice.GetCellA1(sessionId, "CER by Feature", "B1", true, out outStatus);
//2. exception
xlservice.GetRangeA1(sessionId, "CER by Feature", "H19:H21", true, out outStatus);
// Close workbook. This also closes session.
xlservice.CloseWorkbook(sessionId);
}
catch (SoapException e)
{
Console.WriteLine("SOAP Exception Message: {0}", e.Message);
}
}
}
}
I am totally new to the silverlight and sharepoint developping, I search around but didn't get any luck, just found another post here, any one could help me?
This appears to be an oustanding issue, but two workarounds I found so far:
1) Requiring a change in App.config.
http://social.technet.microsoft.com/Forums/en-US/sharepoint2010programming/thread/ab2a08d5-2e91-4dc1-bd80-6fc29b5f14eb
2) Indicating to rebuild service reference with svcutil instead of using Add Service Reference:
http://social.msdn.microsoft.com/Forums/en-GB/sharepointexcel/thread/2fd36e6b-5fa7-47a4-9d79-b11493d18107