hitting an endpoint from angular8 returns 404 - api

This is my first exercise in angular8. I am on the attempt to make a form that consumes an API written in springboot. The api written in spring-boot is never executed when trying to consume it from angular8 and here is the endpoint
http://localhost:8080/api/startreg
#PostMapping("/startreg")
public ResponseData<Activity> addReg(
#RequestParam(value="firstDate") String firstDate,#RequestParam(value="secondDate") String secondDate
,#RequestParam(value="username") String username) {
try {
Here is the service.ts script
private baseUrl = 'http://localhost:8080/api/startreg';
createReg(activity: Object): Observable<Object> {
return this.http.post('${this.baseUrl}', activity);
}
the html file of the angular8 is shown
<form (ngSubmit)="onSubmit()">
<div class="col-md-3 col-sm-5 col-xs-12 gutter">
<div class="sales">
<h2>From:</h2>
<div class="btn-group">
<select [(ngModel)]="activity.firstDate" class="form-control" name="firstDate">
when I attempt to submit the form, from the browser console below error
HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4202/$%7Bthis.baseUrl%7D", ok: false, …}
Please where I am getting it wrong

Because this.http.post('${this.baseUrl}', activity); won't invoke service with the value of this.baseUrl, you can find out why according to the error message.
The URL you passed to post is still a string not a variable.
Please modify service.ts as follows:
...
return this.http.post(this.baseUrl, activity);
}
UPDATE
Another problem is your service consumes request parameters, so you have to pass these URL arguments for HTTP request in service.ts.
The valid URL should look like this:
http://localhost:8080/api/startreg?firstDate=XXX&secondDate=XXX&username=XXX
But I am not familar with TypeScript, so I don't know how to do this. Maybe you can refer to Angular2 - Http POST request parameters.
BTW, I strongly recommend that you should use #RequestBody rather than #RequestParam for your POST service.

Related

Login issue with Restassured api testing

I tried to generate the token from login request.It is successful in postman tool and success in soapui groovy script.But I couldnot do via rest assured library.Below are the screenshot where the request uses Body - form-data with username and password.
I have tried the using queryparams, formparam but getting the below error.Kindly help me to solve the error.
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.4.4</center>
</body>
</html>
Rest assured code:
Map<String, String> formParams = new HashMap<>();
formParams.put("username", "test");
formParams.put("password", "welcome");
Response response = RestAssured.given().config(RestAssured.config().redirect(redirectConfig().followRedirects(false)).encoderConfig(EncoderConfig.encoderConfig().encodeContentTypeAs("multipart/form-data", ContentType.TEXT)))
.queryParams(formParams)
.post("http://posturl");
You are sending the parameters as a query, not as form params.
Also, looks like you need to follow the redirect, since you're getting a 301, so you need followRedirects(true) instead of false.
You need to do it this way:
Response response = RestAssured.given()
.config(RestAssured.config()
.redirect(new RedirectConfig().followRedirects(true))
.encoderConfig(EncoderConfig
.encoderConfig()
.encodeContentTypeAs("multipart/form-data", ContentType.TEXT)))
.formParams(formParams)
.post("http://posturl");

Dropwizard authentication header token

I am trying to implement OAuth2 authentication in a Dropwizard web-application. I have created the required Authenticator and Authorizer classes and added the code supplied in the Dropwizard manual in my Application's run-method as follows:
environment.jersey().register(new AuthDynamicFeature(
new OAuthCredentialAuthFilter.Builder<User>()
.setAuthenticator(new TokenAuthenticator(service))
.setAuthorizer(new TokenAuthorizer())
.setPrefix("Bearer")
.buildAuthFilter()));
environment.jersey().register(RolesAllowedDynamicFeature.class);
//If you want to use #Auth to inject a custom Principal type into your resource
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
My required behavior is that after my client has logged in by providing his/her credentials on my login page, I want to redirect the client to a greeting page I have created using Dropwizard Views and is under the path: "/me" as follows:
//After succesfull login and token generation
return Response.seeOther(new URI("/me")).build(); // redirect to greeting page
And my greeting resource looks as follows:
#Path("/me")
#Produces(MediaType.TEXT_HTML)
public class UserResource {
#GET
public UserView getView(#Auth User user) {
return new UserView(user);
}
}
Currently I am getting a "Credentials are required to access this resource." response after logging in. After some reading on token authentication (nice explanation here) I picked up that the token must be sent from the client in the header of each request. So my question is how do I tell the user's browser (client) to include the token in the header of future requests?
I managed to solve this by doing the following:
In order to verify the user, a token must be sent in the header of the request in the form of Authorization: Bearer <token-value>. This token is sent by the server upon authentication and must be stored by the client / user to be sent in future requests. I managed to store the token by using an ajax request when my login form is submitted as follows:
<#-- Handle form submission response to save the token on the client side-->
<script>
$('#loginForm').submit(function(event){
event.preventDefault();
$.ajax({
url: $(this).attr('action'),
type: 'POST',
data : $(this).serialize(),
dataType: 'json',
success: function(data){
//alert("The server says success!!: " +data);
console.log(data);
window.sessionStorage.accessToken = data.token;
window.location = data.url;
},
error: function(data){
alert("The server says error! : ");
console.log(data);
}
});
});
</script>
The login resource then produces JSON which is received in the data-variable in the code above. The required token resides in data.token - which is then stored. I added a second entry in the JSON named "url" to indicate the path to redirect to after successful authentication.
Now the token is stored on the client side when needed. In order to send this token in the request header, I needed to alter my approach to using the Views provided by Dropwizard. Instead of directly requiring authentication, I split the View's resource and the authenticated data resources. To clarify consider the following example. A user logs in, gets the token and then goes to a page that displays his/her username. For the page, a View resource is created with a .ftl file to serve as a template. Something like:
#Path("/me")
#Produces(MediaType.TEXT_HTML)
public class UserResource {
#GET
public UserView getView() {
return new UserView();
}
}
and...
public class UserView extends View {
public UserView() {
super("user.ftl");
}
}
And user.ftl:
<#include "include/head.html">
<#include "include/header.html">
<!-- Header -->
<div id ="headerWrapper">
</div>
<div class="container-fluid">
<div id="name">
<p>Hello user</p>
</div>
</div>
<#include "include/footer.html">
Now to retrieve the username I create a new resource which produces JSON on a new path. For example:
#Path("/getdetails")
#Produces(MediaType.APPLICATION_JSON)
public class UserDetailsResource {
#GET
#Timed
#UnitOfWork
public User getDetails(#Auth User user) {
return user;
}
}
This resource requires authentication and provides JSON from which the username can be retrieved. Now to get the username and place it inside the view, simply add a script to the users.ftl with an ajax request to the getdetails resource, providing the token in the header and using the result to place the username in the view. See script below.
<script>
$.ajax({
url: '/getdetails',
type: 'GET',
headers: {"Authorization": window.sessionStorage.accessToken},
dataType: 'json',
success: function(data){
//alert("The server says success!!: " +data);
console.log(data);
$("#name").text('Hello '+data.username);
},
error: function(data){
alert("The server says error! : ");
console.log(data);
}
});
</script>

Vue.js click event firing twice with vue-resource [duplicate]

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script>
$.get("http://example.com/", function(data) {
alert(data);
});
</script>
it does an OPTIONS request to that URL, and then the callback is never called with anything.
When it isn't cross domain, it works fine.
Shouldn't jQuery just make the call with a <script> node and then do the callback when its loaded? I understand that I won't be able to get the result (since it is cross domain), but that's OK; I just want the call to go through. Is this a bug, or am I doing something wrong?
According to MDN,
Preflighted requests
Unlike simple requests (discussed above), "preflighted" requests first
send an HTTP OPTIONS request header to the resource on the other
domain, in order to determine whether the actual request is safe to
send. Cross-site requests are preflighted like this since they may
have implications to user data. In particular, a request is
preflighted if:
It uses methods other than GET or POST. Also, if POST is used to send
request data with a Content-Type other than
application/x-www-form-urlencoded, multipart/form-data, or text/plain,
e.g. if the POST request sends an XML payload to the server using
application/xml or text/xml, then the request is preflighted.
It sets custom headers in the request (e.g. the request uses a header such as
X-PINGOTHER)
The OPTIONS is from http://www.w3.org/TR/cors/ See http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/ for a bit more info
If you're trying to POST
Make sure to JSON.stringify your form data and send as text/plain.
<form id="my-form" onSubmit="return postMyFormData();">
<input type="text" name="name" placeholder="Your Name" required>
<input type="email" name="email" placeholder="Your Email" required>
<input type="submit" value="Submit My Form">
</form>
function postMyFormData() {
var formData = $('#my-form').serializeArray();
formData = formData.reduce(function(obj, item) {
obj[item.name] = item.value;
return obj;
}, {});
formData = JSON.stringify(formData);
$.ajax({
type: "POST",
url: "https://website.com/path",
data: formData,
success: function() { ... },
dataType: "text",
contentType : "text/plain"
});
}
Just change the "application/json" to "text/plain" and do not forget the JSON.stringify(request):
var request = {Company: sapws.dbName, UserName: username, Password: userpass};
console.log(request);
$.ajax({
type: "POST",
url: this.wsUrl + "/Login",
contentType: "text/plain",
data: JSON.stringify(request),
crossDomain: true,
});
I don't believe jQuery will just naturally do a JSONP request when given a URL like that. It will, however, do a JSONP request when you tell it what argument to use for a callback:
$.get("http://metaward.com/import/http://metaward.com/u/ptarjan?jsoncallback=?", function(data) {
alert(data);
});
It's entirely up to the receiving script to make use of that argument (which doesn't have to be called "jsoncallback"), so in this case the function will never be called. But, since you stated you just want the script at metaward.com to execute, that would make it.
In fact, cross-domain AJAX (XMLHttp) requests are not allowed because of security reasons (think about fetching a "restricted" webpage from the client-side and sending it back to the server – this would be a security issue).
The only workaround are callbacks. This is: creating a new script object and pointing the src to the end-side JavaScript, which is a callback with JSON values (myFunction({data}), myFunction is a function which does something with the data (for example, storing it in a variable).
I had the same problem. My fix was to add headers to my PHP script which are present only when in dev environment.
This allows cross-domain requests:
header("Access-Control-Allow-Origin: *");
This tells the preflight request that it is OK for the client to send any headers it wants:
header("Access-Control-Allow-Headers: *");
This way there is no need to modify the request.
If you have sensitive data in your dev database that might potentially be leaked, then you might think twice about this.
In my case, the issue was unrelated to CORS since I was issuing a jQuery POST to the same web server. The data was JSON but I had omitted the dataType: 'json' parameter.
I did not have (nor did I add) a contentType parameter as shown in David Lopes' answer above.
I was able to fix it with the help of following headers
Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Credentials
Access-Control-Allow-Methods
If you are on Nodejs, here is the code you can copy/paste.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin','*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH');
next();
});
It's looking like Firefox and Opera (tested on mac as well) don't like the cross domainness of this (but Safari is fine with it).
You might have to call a local server side code to curl the remote page.

kinvey rest api upload

I'm trying to upload on Kinvey using REST API method.
I can successfully get the google storage URL link provided after sending a 'POST' request to https://baas.kinvey.com/blob/:myAppId
The problem is when I'm sending a 'PUT' request to the google storage URL, I'm getting this error:
XMLHttpRequest cannot load (my storage.google URL). Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin (my localhost) is therefore not allowed access.
This appears to be a fairly standard CORS error (which you can read a LOT more about over here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS ) , which takes place when you are making a cross-origin request. There's a lot of different ways that you can approach this issue, but the easiest would probably be to use one of our SDK's to help you. If you take a look over at http://devcenter.kinvey.com/html5/downloads you will find an SDK that you can include in your projects and guides / documentation for it in the top navigation.
File uploads using the HTML5 library are fairly trivial as well. Here's some sample code that I have whipped up:
HTML portion:
<input type="file" name="_file" id="_file" onchange="fileSelected();" />
<div id="fileinfo">
<div id="filename"></div>
<div id="filetype"></div>
</div>
Javascript portion:
function fileSelected(){
var oFile = document.getElementById('_file').files[0];
var oReader = new FileReader();
oReader.onload = function(e) {
document.getElementById('fileinfo').style.display = 'block';
document.getElementById('filename').innerHTML = 'Name: ' + oFile.name;
document.getElementById('filetype').innerHTML = 'Type: ' + oFile.type;
};
oReader.readAsDataURL(oFile);
fileUpload(oFile);
}
function fileUpload(file) {
var file = document.getElementById('_file').files[0];
var promise = Kinvey.File.upload(file,{
filename: document.getElementById('fileinfo').toString(),
mimetype: document.getElementById('filetype').toString()
})
promise.then(function() {
alert("File Uploaded Successfully");
}, function(error){
alert("File Upload Failure: " + error.description);
});
}
This will be slightly different for each of Kinvey's Javascript libraries, but should follow roughly the same outline. Get file, call Kinvey.File.Upload asynchronously, and let the SDK do it's magic. This should handle all the ugliness of CORS for you.
Thanks,

wcf service doesn't allow POST

I'm quite new to webervices in general and am getting stuck in (I think) configuring IIS and the webservice itself.
I created a wcf webservice in MVS 2010 and hosted it on IIS7.5 on windows 7.
I use soapUI 4.5.0 to post a message generated from the same wsdl description I created the webservice contract with. Issue is that I get 405 due to the fact that http POST not seems to be supported by the webservice or webserver.
Even though I had the idea the error I get would be sufficient to solve my problem, my lack of knowledge about IIS and webservices makes I can't find the right solution.
Below as much information as I could think of. Hope it is of any help and someone can guide me in the right direction.
Configurations made in IIS:
Authorization rule: allow, all users
Directory browsing: enabled
Handler mappings: features permissions: read, script and execute
Handler mappings: added *.wsdl -> ProtocolSupportModule -> GET, HEAD, OPTIONS, TRACE, POST
Application pools: added entry with identity NetworkService using
.net fw 4.0
This is the message sent:
RAW:
POST http: x.x.x.x:21378/ HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="/BootNotification"
XML:
<soap:Envelope xmlns:soap="org/2003/05/soap-envelope" xmlns:ns="urn://Ocpp/Cs/2012/02/">
<soap:Header/>
<soap:Body>
<ns:bootNotificationResponse>
<ns:status>Accepted</ns:status>
<ns:currentTime>${now}</ns:currentTime>
<ns:heartbeatInterval>900</ns:heartbeatInterval>
</ns:bootNotificationResponse>
</soap:Body>
</soap:Envelope>
This is the result returned:
I truncated it to limit the size of this post.
RAW:
HTTP/1.1 405 Method Not Allowed
Cache-Control: private
Allow: GET, HEAD, OPTIONS, TRACE
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Thu, 07 Jun 2012 07:58:09 GMT
Content-Length: 5611
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns=".org/1999/xhtml">
<head>
<title>IIS 7.5 Detailed Error - 405.0 - Method Not Allowed</title>
<style type="text/css">
...
...
...
<div class="content-container">
<fieldset><legend>Most likely causes:</legend>
<ul> <li>The request sent to the Web server used an HTTP verb that is not allowed by the module configured to handle the request.</li> <li>A request was sent to the server that contained an invalid HTTP verb.</li> <li>The request is for static content and contains an HTTP verb other than GET or HEAD.</li> <li>A request was sent to a virtual directory using the HTTP verb POST and the default document is a static file that does not support HTTP verbs other than GET or HEAD.</li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><legend>Things you can try:</legend>
<ul> <li>Verify the list of verbs enabled for the module handler this request was sent to, and ensure that this verb should be allowed for the Web site.</li> <li>Check the IIS log file to see which verb is not allowed for the request.</li> <li>Create a tracing rule to track failed requests for this HTTP status code. For more information about creating a tracing rule for failed requests, click here. </li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><legend>Links and More Information</legend>
This error means that the request sent to the Web server contained an HTTP verb that is not allowed by the configured module handler for the request.
<p>View more information »</p>
</fieldset>
</div>
</div>
</body>
</html>
XML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ".org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns=".org/1999/xhtml">
<head>
<title>IIS 7.5 Detailed Error - 405.0 - Method Not Allowed</title>
<style type="text/css">
...
</head>
<body>
<div id="header"><h1>Server Error in Application "SHENZIWEBSERVICEDEPLOYED"</h1></div>
<div id="server_version"><p>Internet Information Services 7.5</p></div>
<div id="content">
<div class="content-container">
<fieldset><legend>Error Summary</legend>
<h2>HTTP Error 405.0 - Method Not Allowed</h2>
<h3>The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used.</h3>
</fieldset>
</div>
<div class="content-container">
...
</div>
<div class="content-container">
<fieldset><legend>Most likely causes:</legend>
<ul> <li>The request sent to the Web server used an HTTP verb that is not allowed by the module configured to handle the request.</li> <li>A request was sent to the server that contained an invalid HTTP verb.</li> <li>The request is for static content and contains an HTTP verb other than GET or HEAD.</li> <li>A request was sent to a virtual directory using the HTTP verb POST and the default document is a static file that does not support HTTP verbs other than GET or HEAD.</li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><legend>Things you can try:</legend>
<ul> <li>Verify the list of verbs enabled for the module handler this request was sent to, and ensure that this verb should be allowed for the Web site.</li> <li>Check the IIS log file to see which verb is not allowed for the request.</li> <li>Create a tracing rule to track failed requests for this HTTP status code. For more information about creating a tracing rule for failed requests, click here. </li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><legend>Links and More Information</legend>
This error means that the request sent to the Web server contained an HTTP verb that is not allowed by the configured module handler for the request.
<p>View more information »</p>
</fieldset>
</div>
</div>
</body>
</html>
This is part of the generated servicecontract (wsdl /language:CS /serverInterface
// CODEGEN: The optional WSDL extension element 'PolicyReference' from namespace 'http://schemas.xmlsoap.org/ws/2004/09/policy' was not handled.
[ServiceContract(Name = "CentralSystemServiceSoap", Namespace = "urn://Ocpp/Cs/2010/08/")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
[System.Web.Services.WebServiceBindingAttribute(Name="CentralSystemServiceSoap", Namespace="urn://Ocpp/Cs/2010/08/")]
public interface ICentralSystemServiceSoap {
/// <remarks/>
[OperationContract]
[System.Web.Services.Protocols.SoapHeaderAttribute("chargeBoxIdentity")]
[System.Web.Services.WebMethodAttribute()]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("/BootNotification", RequestElementName = "bootNotificationRequest", RequestNamespace = "urn://Ocpp/Cs/2010/08/", ResponseElementName = "bootNotificationResponse", ResponseNamespace = "urn://Ocpp/Cs/2010/08/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("status")]
RegistrationStatus BootNotification(string chargePointVendor, string chargePointModel, string chargePointSerialNumber, string chargeBoxSerialNumber, string firmwareVersion, string iccid, string imsi, string meterType, string meterSerialNumber, out System.DateTime currentTime, [System.Xml.Serialization.XmlIgnoreAttribute()] out bool currentTimeSpecified, out int heartbeatInterval, [System.Xml.Serialization.XmlIgnoreAttribute()] out bool heartbeatIntervalSpecified);
I didn't understand how your service is built and what you have done there, but from my experience, this is a simple way to create a wcf RESTful service that supports POST requests:
http://www.codeproject.com/Articles/201901/CREATE-RESTful-WCF-Service-API-Using-POST-Step-By
Update according to the comments:
try using that:
[OperationContract]
[WebInvoke(Method = "POST")]
[System.Web.Services.Protocols.SoapHeaderAttribute("chargeBoxIdentity")]
[System.Web.Services.WebMethodAttribute()]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("/BootNotification", RequestElementName = "bootNotificationRequest", RequestNamespace = "urn://Ocpp/Cs/2010/08/", ResponseElementName = "bootNotificationResponse", ResponseNamespace = "urn://Ocpp/Cs/2010/08/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("status")]
RegistrationStatus BootNotification(string chargePointVendor, string chargePointModel, string chargePointSerialNumber, string chargeBoxSerialNumber, string firmwareVersion, string iccid, string imsi, string meterType, string meterSerialNumber, out System.DateTime currentTime, [System.Xml.Serialization.XmlIgnoreAttribute()] out bool currentTimeSpecified, out int heartbeatInterval, [System.Xml.Serialization.XmlIgnoreAttribute()] out bool heartbeatIntervalSpecified);
UPDATE
try doing that:
On IIS 7.5 -> YourWebsite -> Handler Mappings
Choose "Add module mapping" option on the right side of the panel
In "Request path" field enter *.wsdl
In "Module" field enter "ProtocolSupportModule"
Click on "Request restrictions" and go to Verbs tab
Enter POST verb
Save changes