i have this client angular 1.5 code
var getGroupForUser = function () {
var deferred = $q.defer();
$http.get(env.domain+'/Voices/authorize').then(
function successCallback(response) {
// self.isAdOps = response.data.;
deferred.resolve(response.data);
}, function errorCallback(response) {
console.log(response.data.errorMsg);
self.isAdOps = true;
deferred.reject("data: "+response.data+" code:"+response.status+" "+response.statusText+", please look at the web console");
});
return deferred.promise;
};
and this jersey java code on the server:
#Path("/Voices")
public class VoicesOperation {
#Path("/search")
#GET
#Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public List<VoiceUi> search(#QueryParam("q") String searchTerm) throws Exception {...
}
#Path("/authorize")
#GET
#Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public String authorize() {
logger.info("in voicesOperation - authorization");
logger.error("checking error log ==== in voicesOperation - authorization");
However i get in the server an error:
javax.ws.rs.NotFoundException: HTTP 404 Not Found
what am i missing?
Just modify your like below and try:-
public String authorize(#Context UriInfo info) {
.
.
}
Related
In my ionic 5.0.0 application I'm using cordova's native HTTP to make the rest calls. Below is the code snippet of my logout function.
But when i execute this function i'm getting following error.
"advanced-http: \"data\" argument supports only following data types: String"
logout() {
this.setData("url", "/web/oauth/revoke-token");
let apiUrl = this.getBaseUrl() + this.getData("url");
const headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Authorization': 'Basic Y2hyR3liUnBxQUR3X2VDemw5dzc0cHU4dXNnYTpKdmZ1azgyYnBUQlVnNDJ6NU1hZFhXOWJPeElh'
};
const params = {
'companyId': this.getData("COMPANY_ID"),
'token': this.getData("ACCESS_TOKEN"),
'client_id': this.getData("CLIENT_ID"),
'token_type_hint': 'access_token'
};
this.nativeHttp.post(apiUrl, params, headers).then(response => {
console.log("success response: "+response);
})
.catch(error => {
console.log("error response: "+error);
});
console.log("finished");
}
Here is my Spring controller which receives the params.
#RequestMapping(value = "/oauth/revoke-token", method = RequestMethod.POST)
#ResponseBody
public ResponseEntity<Object> logout(HttpServletRequest request) {
String clientId = request.getParameter(OAuth2Constants.CLIENT_ID);
String token = request.getParameter(OAuth2Constants.TOKEN);
String tokenTypeHint = request.getParameter(OAuth2Constants.TOKEN_TYPE_HINT);
String companyId = request.getParameter(WebConstants.COMPANY_ID_PARAMETER);
}
But unfortunately all params receives in the controller as null.
Can someone help me?
Finally I found a solution for the issue. Simply set the data serializer for http request as follows before doing the post call.
this.nativeHttp.setDataSerializer( "urlencoded" );
I have a rest API implemented in Java (MSF4J codegen from swagger) and a swagger 2 definition that describes it.
A swagger UI is hosted on a web server. The API is deployed on a VM somewhere on the internet.
My Problem is that the "try it out" function of the swagger UI doesn't work. I always get a "401 Unauthorized". When I take the curl command from the UI and paste it into my terminal it works.
Last week I didn't have HTTPS or Basic Authentication - just HTTP - and it worked fine. Now I don't know why it doesn't work.
Since I changed the swagger definition to https the UI makes an OPTIONS request. I implemented that, but I get 401 responses.
The certificate comes from Lets Encrypt and is used by an apache web server. The apache is a proxy to the rest api on the same machine.
Here is my authentication interceptor:
public class BasicAuthSecurityInterceptor extends AbstractBasicAuthSecurityInterceptor {
#Override
protected boolean authenticate(String username, String password) {
if (checkCredentials(username, password))
return true;
return false;
}
private boolean checkCredentials(String username, String password) {
if (username.equals("testuser"))
return BCrypt.checkpw(password, "$2a$10$iXRsLgkJg3ZZGy4utrdNyunHcamiL2RmrKHKyJAoV4kHVGhFv.d6G");
return false;
}
}
Here is a part of the api:
public abstract class DeviceApiService {
private static final Logger LOGGER = LogManager.getLogger();
public abstract Response deviceGet() throws NotFoundException;
public abstract Response deviceIdAvailableLoadGet(Integer id, Long from, Long to, String resolution)
throws NotFoundException;
public abstract Response deviceIdGet(Integer id) throws NotFoundException;
protected Response getOptionsResponse() {
String allowedOrigin = "";
try {
allowedOrigin = PropertyFileHandler.getInstance().getPropertyValueFromKey("api.cors.allowed");
} catch (IllegalArgumentException | PropertyException | IOException e) {
LOGGER.error("Could not get allowed origin.", e);
}
Response response = Response.ok().header("Allow", "GET").header("Access-Control-Allow-Origin", allowedOrigin)
.header("Access-Control-Allow-Headers", "authorization, content-type").build();
return response;
}
}
public class DeviceApi {
private final DeviceApiService delegate = DeviceApiServiceFactory.getDeviceApi();
// #formatter:off
#GET
#Produces({ "application/json" })
#io.swagger.annotations.ApiOperation(
value = "Get devices",
notes = "",
response = Device.class,
responseContainer = "List",
authorizations = { #io.swagger.annotations.Authorization(value = "basicAuth") },
tags = { "Device", }
)
#io.swagger.annotations.ApiResponses(
value = { #io.swagger.annotations.ApiResponse(
code = 200,
message = "200 OK",
response = Device.class,
responseContainer = "List")
})
public Response deviceGet() throws NotFoundException {
return delegate.deviceGet();
}
#OPTIONS
#Consumes({ "application/json" })
#Produces({ "application/json" })
#io.swagger.annotations.ApiOperation(value = "CORS support", notes = "", response = Void.class, authorizations = {
#io.swagger.annotations.Authorization(value = "basicAuth") }, tags = { "Device", })
#io.swagger.annotations.ApiResponses(value = {
#io.swagger.annotations.ApiResponse(code = 200, message = "Default response for CORS method", response = Void.class) })
public Response deviceOptions() throws NotFoundException {
return delegate.getOptionsResponse();
}
}
EDIT:
This are the headers of the request the swagger ui creates:
Accept: text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: de,en-US;q=0.7,en;q=0.3
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Connection: keep-alive
DNT: 1
Host: api.myfancyurl.com
Origin: http://apidoc.myfancyurl.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/61.0
It seems that the authorization header is missing. When I edit the request and resend it with the authorization header and encoded credentials it works.
But I don't know why swagger doesn't add this header. Should one accept all options requests without authorization?
I am building my backend and I need to be able to exchange a request/response object from angular.js to my backend (JAX-RS, Jersey).
My backend currently looks like this:
#POST
#Path("/search")
#ApiResponses(value = {#ApiResponse(code=200,message="returns results"),
#ApiResponse(code=404,message="not found")})
#Produces({ "application/json" })
public Response getPostShop(
#QueryParam("keyphrase") String keyphrase,
#QueryParam("product") String product,
#QueryParam("priceRange") List<Double> priceRange,
#Context SecurityContext securityContext)
throws NotFoundException {
SearchRequest searchRequest = new SearchRequest();
searchRequest.setKeyphrase(keyphrase);
searchRequest.setProduct(product);
searchRequest.setPriceRange(priceRange);
//do something with the "searchRequest"
return Response.ok(searchResponse).build();
}
Angular.Js (Something like this)
response.compose = function(searchRequest) {
return $http({
method: 'POST', //or GET
url: '/search',
data: {
searchRequest : searchRequest
},
headers: {'Content-Type':'application/json'}
});
}
where searchRequest:
$scope.searchRequest = {
'keyphrase' : $scope.keyphrase,
'product' : $scope.product,
'priceRange' : $scope.priceRange,
};
NEW GET request:
#GET
#Path("/testkeyphrase")
#ApiResponses(value = {#ApiResponse(code=200,message="returns results"),
#ApiResponse(code=404,message="not found")})
#Produces({ "application/json" })
#Consumes({ "application/json" })
public Response getTestKeyphrase(
#ApiParam(value="keyphrase that the user searches for..", required=true) TestSearchRequest testSearchRequest,
#Context SecurityContext securityContext)
throws NotFoundException {
String kyphrase = testSearchRequest.getKeyphrase();
return Response.ok(testSearchRequest).build();
}
and the TestSearchRequest is:
public class TestSearchRequest {
public TestSearchRequest(String keyphrase) {
this.setKeyphrase(keyphrase);
}
private String keyphrase;
public String getKeyphrase() {
return keyphrase;
}
public void setKeyphrase(String keyphrase) {
this.keyphrase = keyphrase;
}
}
What I need is instead of receiving all the individual parameters, to receive directly the searchRequest object and send back the SearchResponse object respectively (in JSON). Also I need the parameters to be in the body of the request and not in the URI.
Any ideas?
I have built an application with Spring-boot and AngularJS with the REST End Point application. I got a little stuck with #RequesMapping in Spring Controller I've made. The problem is, I have the example url:
"localhost:8080/foo/bar/api/cardGenerated/0102".
'01' is first parameter and '02' is second parameter. How can I mapped into #RequestMapping Spring controller to get a url above.
Here's my controller :
#RestController
#RequestMapping("/api")
public class CardGeneratedResource {
#RequestMapping(value = "/cardGenerated/{branchCode}{cardType}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<CardGenerated> get(#PathVariable("branchCode") String branchCode,
#PathVariable("cardType") String cardType,
HttpServletResponse response) {
log.debug("REST request to get CardGenerated : " + branchCode + " and " + cardType);
CardGenerated cardGenerated = cardGeneratedRepository.
findTopByBranchCodeAndCardTypeOrderByCardNumberDesc(branchCode, cardType);
if (cardGenerated == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(cardGenerated, HttpStatus.OK);
}
}
so this is my AngularJS $resource:
'use strict';
angular.module('itmApp')
.factory('CardGenerated', function ($resource) {
return $resource('api/cardGenerated/:branchCode:cardType', {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
}
});
});
I always got 'Failed to load resource: the server responded with a status of 404 (Not Found)'.
Here you are missing / .
You have two path variable here.so default url is
localhost:8080/foo/bar/api/cardGenerated/FIRST_PATH_VARIABLE/SECOND_PATH_VARIABLE
branchCode (First path variabel)
cardType (Second path variable)
#RequestMapping(value = "/cardGenerated/{branchCode}/{cardType}"
And in frontend side too the same mistake while registering factory definition.
api/cardGenerated/:branchCode/:cardType'
All method is like
#RestController
#RequestMapping("/api")
public class CardGeneratedResource {
#RequestMapping(value = "/cardGenerated/{branchCode}/{cardType}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<CardGenerated> get(#PathVariable("branchCode") String branchCode,
#PathVariable("cardType") String cardType,
HttpServletResponse response) {
log.debug("REST request to get CardGenerated : " + branchCode + " and " + cardType);
CardGenerated cardGenerated = cardGeneratedRepository.
findTopByBranchCodeAndCardTypeOrderByCardNumberDesc(branchCode, cardType);
if (cardGenerated == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(cardGenerated, HttpStatus.OK);
}
}
and angular factory is like
'use strict';
angular.module('itmApp')
.factory('CardGenerated', function ($resource) {
return $resource('api/cardGenerated/:branchCode/:cardType', {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
}
});
});
NOTE: First try with any rest client or postman and make sure backend api is working properly also angular side check parameters are being passed correctly.
I started with one of the Spring getting started samples. I am extending it to match my scenario. I am trying to use the PUT method on a web service call. I get the error message "Request method 'PUT' not supported". But, execution makes it into the web service. The error occurs after/during returning. Is there something I need to do to my objects to allow the to be returned from non-GET HTTP methods?
I am calling into the web service with a test stub written in python. I have not posted that code since execution is getting into the web service.
Following is the Spring code:
#ComponentScan
#EnableAutoConfiguration
#Controller
#RequestMapping("/jp5/rest/message")
public class MessageRestService
{
#RequestMapping(method=RequestMethod.PUT, value="/test")
public testResult test()
{
// I hit a breakpoint here:
return new testResult(true, "test");
}
}
class testResult
{
public testResult( boolean success, String message )
{
setSuccess(success);
setMessage(message);
}
//#XmlElement
private boolean success;
//#XmlElement
private String message;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Edit
There is no stack trace, just this in the server output:
2013-11-13 21:26:20.976 WARN 5452 --- [nio-8888-exec-1]
o.s.web.servlet.PageNotFound :
Request method 'PUT' not supported
Here is the python as requested. And, I think the answer to the problem lies in "'allow': 'GET, HEAD'" in the response. So, how do I allow other methods? Maybe I need to think about an applicationContext?
path = '/jp5/rest/message/test'
method = 'PUT'
body = ''
target = urlparse(self.uri+path)
h = http.Http()
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=UTF-8'
}
response, content = h.request(
target.geturl(),
method,
body,
headers)
print response
output from the print:
{'status': '405', 'content-length': '1045', 'content-language': 'en-US', 'server':
'Apache-Coyote/1.1', 'allow': 'GET, HEAD', 'date': 'Thu, 14 Nov 2013 02:26:20 GMT',
'content-type': 'text/html;charset=utf-8'}
I am starting the server like this:
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Thanks
Thanks for the pointers. The solution is to add a #ResponseBody:
public #ResponseBody testResult test()
{
return new testResult(true, "test");
}