I have writing Java code Using Jersey library to call Rest APIs.
For my first method to display all blogs i have written the code like
return webResource.path(ConfigurationUtil.LIST_BLOGS).header(ConfigurationUtil.AUTHENTICATION_HEADER, authentication)
.accept(MediaType.APPLICATION_XML_TYPE).get(new GenericType<List<CommunityBean>>() {
});
which lists all the blogs.. As my LIST_BLOGS string is like
public static final String LIST_BLOGS = "api/blogs.xml";
Its works fine..
Now I'm trying to write a code for a method where I want to extract only 2 blogs and not all
so my url will be like
public static final String LIST_BLOGS = "api/blogs.xml?limit=2";
As I am not able to send the parameter from the wrapper file to ConfigurationUtil file and I used the way as
public List<BlogBean> searchBlogsXml(String limit) {
final String SEARCH_BLOGS="api/blogs.xml?limit="+limit;
return webResource.path(SEARCH_BLOGS).header(ConfigurationUtil.AUTHENTICATION_HEADER, authentication)
.accept(MediaType.APPLICATION_XML_TYPE).get(new GenericType<List<BlogBean>>() {
});
}
When i used like above i am getting 406 error..
Why so how to avoid this ?
Please give suggestions..
You can attach a query param like this;
resource.queryParam("limit", 2).get(MyObject.class);
Related
I had this problem since a week, I didn't found enough resources.
I have a java application which consume an external API, I want to test my application using wiremock.
When I want to send a file it's always shown 404 Not found.
I found that the issue is that wiremock not preserving the Host header value, so I have this code below, but it always doesn't work.
I tried the real API and it's working perfectly using WireMock Record & Playback feature, but I specify the -preserve-host-header option(without this it's getting 404 Not Found)
My service that I want to test (I don't have controllers):
#Service
public class Bank{
//This method is working
public String hello(String hello){
return exernalAPI.get("hello").toString(); // It's just an example
}
//This method is not working in test(404)
public void uploadFile(String inputStrum...){
//The code here is used to send the file to an external API using method post
}
}
I did a record and Playback to capture the request and the response from the real extern API,
Class test:
#AutoConfigureWireMock(port=0)
#ContextConfiguration(classes={Bank.class})
public class BankTest{
#Autowired
public Bank bank;
#Test //The test is passing
public void helloTest(){
String expected = resourse.getResource("classpath:response/helloMessage.txt").toString(); //Get the captured response
String actual = bank.hello("Jack"); //this return Hi Jack and it's working
assertEquals(expected,actual);
}
#Test //This test is not passing
public String uploadFileTest(){
InputSteam is = getInputStream();
//code to get inputStream
Resource expected= resourse.getResourse("classpath:responses/upload_response.json");
String expected = expected.toString();
is.setContent(resource.getResource("classpath:file_to_upload.zip"));
String actual = bank.uploadFile(is); // Here i have 404 not found
assertEquals(expected,actual);
}
after several searches I found that I have to preserve the Host header using something like this :
preserveHostHeader(true);
I'm working on Android app which connects to REST and invokes a method. This is Embarcadero REST DataSnap.
Using parameters like "#Query" is good when you invoke method like that:
www.app.net/api/searchtypes/862189/filters?Type=6&SearchText=School
However, here methods are invoked differently:
/datasnap/rest/some_class/some_method/some_parameter
Below is simple class to handle parameter which goes in request body:
public class Dane {
private int NAGL;
public Dane(int NAGL) {
this.NAGL = NAGL;
}
}
When I try to use Retrofit annotation #Query, for example:
#POST("datasnap/rest/TstBaseMethods/%22SelectSQL%22/{aSelectSQL}")
Call<Logowanie> selectSQL(#Header("Authorization") String credentials,#Body Dane json,#Query("aSelectSQL") String aSelectSQL);
String dane = Credentials.basic("admin","admin");
Dane json = new Dane(11101);
Call<Logowanie> sql = gerritAPI.selectSQL(dane,json,"select n.datadok from nagl n where n.id_nagl =:NAGL");
and I launch the app, I see in logs
TstBaseMethods.SelectSQL: {aSelectSQL} << {"NAGL":11101}
The content of aSelectSQL is not sent to the server. I've already noticed that if I hardcode the content into URL and I invoke this as below, it works:
#POST("datasnap/rest/TstBaseMethods/%22SelectSQL%22/select%20n.datadok%20from%20nagl%20n%20where%20n.id_nagl%3D%3Anagl")
Call<Logowanie> selectSQL(#Header("Authorization") String credentials,#Body Dane json);
Is there any way to pass properly content of the parameter to the server? It won't be good to hardcode all parameters in URL.
So, in retrofit, the #Query annotation is used for query parameter.
It will add your parameter as a query parameter, for example:
#GET("/api/somePath")
Call<JSONObject> getSomething(#Query("foo") String foo);
...
service.getSomething("bar")
Will actually result in the url:
https://yoursite.com/api/somePath?foo=bar
Here, in your case, you are using {} inside the url, which indicates retrofit that you are adding a path parameter. So your post should be like this
#POST("datasnap/rest/TstBaseMethods/%22SelectSQL%22/{aSelectSQL}")
Call<Logowanie> selectSQL(#Header("Authorization") String credentials,#Body Dane json,#Path("aSelectSQL") String aSelectSQL);
I have created a java web service that does addition function. I also have created an ASP.NET Web API which calls the java web service and displays the result. Lets say i typed in http://localhost:8080/addition/9/6 as the URL with input parameters that the java web service function should add. I get the output data as {"firstNumber":9,"secondNumber":6,"sum":15}. When i run my ASP.NET Web API, i will be redirected to http://localhost:55223/ and i will get the output data as {"firstNumber":9,"secondNumber":6,"sum":15}.
Right now, what i want to do is, when i run my ASP.NET Web API, i should be able to input parameters in the URL of the ASP.NET Web API (http://localhost:55223/addition/9/6) and instead of displaying result straight from Java web service, i want to use the function of the java web service in my API to calculate the sum of the input parameters. Does anyone have an idea on how can i go about doing that? What are the changes that i should make in my codes?
Here are my codes:
ASP.NET Web API codes
RestfulClient.cs
public class RestfulClient
{
private static HttpClient client;
private static string BASE_URL = "http://localhost:8080/";
static RestfulClient()
{
client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<string> addition(int firstNumber, int secondNumber)
{
try
{
var endpoint = string.Format("addition/{0}/{1}", firstNumber, secondNumber);
var response = await client.GetAsync(endpoint);
return await response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
HttpContext.Current.Server.Transfer("ErrorPage.html");
}
return null;
}
}
ApiController.cs
public class ApiController : Controller
{
private RestfulClient restfulClient = new RestfulClient();
public async Task<ActionResult> Index()
{
int firstNumber = 9;
int secondNumber = 6;
var result = await restfulClient.addition(firstNumber, secondNumber);
return Content(result);
}
}
Java web service codes
AdditionController.java
#RestController
public class AdditionController {
private static final String template = " %s";
private static int getSum;
#RequestMapping("/addition/{param1}/{param2}")
#ResponseBody
public Addition addition
(#PathVariable("param1") int firstNumber,#PathVariable("param2") int secondNumber) {
return new Addition(
(String.format(template, firstNumber)), String.format(template, secondNumber));
}
}
Someone please help me thank you so much in advance.
what i want to do is, when i run my ASP.NET Web API, i should be able to input parameters in the URL of the ASP.NET Web API (http://localhost:55223/addition/9/6)
Web API uses many conventions and if you play nicely then things work pretty well. The first thing you need to do is to rename your controller like this:
public class AdditionController : ApiController
{
public async Task<IHttpActionResult> Get(int firstNumber, int secondNumber)
{
var result = await restfulClient.addition(firstNumber, secondNumber);
return Ok(result);
}
}
You will notice a few things in above code:
The controller is called AdditionController. When you type addition in the url, the routing engine will look for a controller named Addition + the word Controller.
It inherits ApiController not Controller.
It has a Get action. If you make a GET request, the API routing engine will search for an action named Get or starting with Get. Thus it will find this action.
The action is returning IHttpActionResult. See my answer here for why.
It uses the extension method named Ok to return an HTTP Status code of 200. This is to follow good restful guidelines and HTTP guidelines.
You can call the above like this:
http://localhost:55223/addition?firstNumber=1&secondNumber=6
If you want to be able to call it like this:
http://localhost:55223/addition/9/6
Then you need to make some changes to the WebApiConfig class. Add this to code before the code for DefaultApi:
config.Routes.MapHttpRoute(
name: "AdditionApi",
routeTemplate: "api/addition/{firstNumber}/{secondNumber}",
defaults: new { action = "Get", controller = "Addition" }
);
Above we are telling the routing engine: Hey routing engine, if the url contains the word api/addition followed by a variable and another variable, then use the Get method of the Addition controller*.
Apologies if this has been answered already - I've had a look and can't find anything.
Using the Play framework, I have defined two controllers - one is a public API that returns JSON, and one is a consumer of this API which presents the JSON as HTML. E.g. my routes file look as follows:
GET /foos controllers.App.foos() #produces HTML
GET /api/foos controllers.API.foos() #produces JSON
A requirement of the project is that our data should only be accessed via our public API. Therefore, the way that I'd like to implement this is to have App.foos() invoke API.foos(), parse the JSON result, and pass it to a template to be rendered. For example:
public App extends Controller {
public static Result foos() {
Result result = API.foos();
// TODO: get the JSON out of the result object
}
}
Can anyone tell me how I can extract the JSON from the result object? I can get the body of the object as an Enumerator using ((SimpleResult)result.getWrappedResult()).body(), but I am still unclear how I can get out the JSON.
Because I am new to the Play framework, perhaps I am going about this wrong and there is an easier/better way to do this?
Many thanks in advance,
James
The easiest way would be to expose the underlying method.
public Api extends Controller {
public static Result foos() {
Ok(foosJson());
}
public static JsValue foosJson() {
// ...
}
}
public App extends Controller {
public static Result foos() {
JsValue json = API.foosJson();
}
}
Just startred using restlet with java and was pleasently surprised how easy it was. However this was with puts. I then started to work with get but couldn't work out how to pass infromation with the get.
With the put it was easy as:
#Put
public Boolean store(Contact contact);
But when i try and do this with get it doesnt work. From reading around i think i have to not pass it any parameters and just have this:
#Get
public Contact retrieve();
and then pass the parameters in a url or something?
But i cant find any info on how to do this. As with put i could just use:
resource.store(user1);
Any help please?
Im pretty sure this is the kind of thing i just need to see an example of and then ill be able to do it easily. Example of how to get the infromation out of the url at the other side would be very helpful aswell.
Thanks
I now have on my client side:
String username = "tom";
ClientResource cr2 = new ClientResource("http://.../ContactManager/contacts/" + username);
ContactResource resource2 = cr2.wrap(ContactResource.class);
resource2.logIn();
On the server side i have:
#Get
public Contact logIn(){
System.out.println("name is " + resource.getAttributes().get("contactId"));
return null;
}
But i am not sure what resource is? It doesnt exist in my program and am not sure what type it needs to be or where to declare it.
A good approach with REST is to specify this contact id within the URI. Something like that: /contacts/mycontactid.
When attaching your resources within the application class, you can define this segment as an attribute (the contact id one in your case).
public class ContactsApplication extends Application {
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/contacts/", ContactsServerResource.class);
router.attach("/contacts/{contactId}", ContactServerResource.class);
return router;
}
}
Then you can have the code provided by Richard in his answer.
Hope it helps you.
Thierry
I know this question was asked along time ago but the answer I think you are looking for is:
Application Code
public class ContactsApplication extends Application {
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/user/", ContactsServerResource.class);
router.attach("/user/{user}", ContactServerResource.class);
return router;
}
}
Resource Code
#Get
public void login()
String userName = (String)this.getRequestAttributes().get("user");
The (String)this.getRequestAttributes().get("user"); allows you extract details from the URL.
Hope this helps
It seems that what you are looking for is something like:
public final Representation get() {
String contactId = request.getAttributes().get("contactId"));
// Find the Contact object with that id
JacksonRepresentation<Contact> result =
new JacksonRepresentation<Contact>(contact);
return result;
}
Also see: how to pass parameters to RESTlet webservice from android? for a similar approach.