Basic auth Spring resttemplate examples and they all use an Account.class. What is it? - rest

Here's a typical example of what I find:
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url,
HttpMethod.GET, request, Account.class);
Account account = response.getBody();
I've googled looking for any reference to the Account.class. So far I've come up empty. I can't find it in Spring 4 JavaDocs. Can anyone tell me where it's documented and is there a Maven dependency that includes the necesssry jars?
Thanks,
Rob

Acoount.class is not a part of any jar. It's a class in your application.
It is used by rest template to map the response to an object. Here is what I mean:
if the response is:
{"name": name, "balance": 1000}
And you have:
class Account {
private String name;
private int balance;
// setters/getters
}
Then the code you provided will return you an instance of the Account.
That's it!

Related

How JAXB mapping is done in Spring boot SOAP webservices

I have a question on JAXB mapping using org.springframework.ws.server.endpoint.annotations.
I was able to generate Java domain object with provided *.xsd. The thing is after I define my endpoint with
#PayloadRoot, I have to wrap my request and response as below to successfully trigger the method and return a result:
#PayloadRoot( localPart = "PmtAuthAddRequest",
namespace = "http://*com/emb/webseries")
#ResponsePayload
public JAXBElement billPayment(#RequestPayload JAXBElement var1){
PmtAuthAddResponseType response=billPaymentHandler.execute(var1.getValue());
return of.createPmtAuthAddResponse(response); // Used ObjectFactory to create JAXBElement.
}`
`
From all the tutorial I see, they dont need to wrap it as JAXBElement to return the correct type, but the below code does not work for me:
`
`#PayloadRoot( localPart = "PmtAuthAddRequest",
namespace = "http://*com/emb/webseries")
#ResponsePayload
public PmtAuthAddResponseType billPayment(#RequestPayload PmtAuthAddRequestType> var1){
PmtAuthAddResponseType response=billPaymentHandler.execute(var1.getValue());
return response;
}`
`
Do you guys know why? How can I resolve this? Thanks
I tried without wrapping it as JAXBElement, but soap UI return with error message:
`no adapter for endpoint [public com.*.*.*.webseries.billpay.CustPayee50InqResponseType com.*.Endpoint.InquirePayeeEndpoint.inquirepayees(com.*.*.*.webseries.billpay.CustPayee50InqRequestType) throws javax.xml.bind.JAXBException]: Is your endpoint annotated with #Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?</faultstring>
`
Actually solved my own question....
The way to do it is to add #XmlRootElement under generated Java class from JAXB2 with below to correctly mapping:
#XmlRootElement(namespace = "http://..*/emb/webseries",name = "CustPayee50InqRequest")
The name should match with the localPart provided name from #PayloadRoot.
Added both for request and response makes it work for me

Spring mvc test case with string in request header and multipart file as a request parameter for a post request

#Controller
#PostMapping("/hello/{studentName}")
public ResponseEntity<Void> method1(
#RequestMapping(value = "/upload/{studentName}", method = RequestMethod.POST)
#ResponseBody
public String saveAuto(
#PathVariable(value = "name") String name,` `
#RequestParam("file") MultipartFile myFile) {
}
}
Hi, I am new to unit test. can anyone please help me for writing test case using mockmvcbuilderrequest..
I tried this but getting 404
mockMvc.perform(MockMvcRequestBuilders.multipart("/hello/{zoneName}","com.example")
.file(file).accept(MediaType.MULTIPART_FORM_DATA_VALUE))
You have 2 options.
Change the rest path and put: "/hello/{studentName}", in this way the test will work as you have explained.
Leave the rest path "/upload/{studentName}" and change the uri in the test from "/hello/{studentName}" to "/upload/{studentName}".
I leave the way to execute the test, with the correction.
mockMvc.perform(
MockMvcRequestBuilders.multipart("/upload/{studentName}","Anu Shree")
.file(file)
.accept(MediaType.MULTIPART_FORM_DATA_VALUE)
)
I hope it helps

Is it possible for a restful webservice to have a parameter in the url?

I was instructed to create webservices ( with Spring-Boot ). My colleague gave me the url of the webservice and it looks like this : http://172.20.40.4:8080/Oxalys_WS/stock/ITM=1559
In general we create a RestController with the url :
#RestController
#RequestMapping("stock")
public class StockController {
#Autowired
private StockService stockService;
#GetMapping(value = "/{code}", produces = "application/json")
public JsonModel getByCode(#PathVariable String code) {
JsonModel jsonModel = new JsonModel();
final Map<String, Object> data = new HashMap<>();
List<Stock> stock = stockService.getByCode(code);
data.put("stock", stock);
data.put("stockTotal", stockService.getTotal(code));
jsonModel.setDatas(data);
return jsonModel;
}
}
So is it normal to create a Restful Spring-Boot webservice with a parameter in the url ?
Spring provides parameter in two standard way.
Query Param : http://172.20.40.4:8080/Oxalys_WS/stock?ITM=1559
Path Variable : http://172.20.40.4:8080/Oxalys_WS/stock/1559
Query Param :- It is a typical old way to pass some value as QueryParam with using of some variable starts with ?(Question Mark) and value is assigned using =(equals).
PathVariable :- this is a newer pattern introduce for REST-api Services. URL must be structured such in a way that this should not look too messy if multiple parameters need to pass within a URL.
For more info Navigate this link
Yes, you can have the one in your URL
When you are required to have the path variable, you can give in the Request URL

Swagger-Springmvc: Getting unknownFields in JSON

I have a REST API which I have configured as follows
#Api(value="rest", description="Sweet blah!!!")
#Controller
public class abc{...}
A method in abc is annotated as follows
#ApiOperation(value="Create Account",
notes="Sweet Blah",
response=Account.class,
nickname="AccountCreation2",
produces= "application/json,application/xml",
consumes="application/json, application/xml")
#ApiImplicitParams(value=
{ #ApiImplicitParam(name="body",value="Sweet Blah.",
required=true, paramType="body", dataType="com.trrr.Account"),
#ApiImplicitParam(name="accountId", value="provides account Id for the new
account",required=true, paramType="path", dataType="Integer")
})
#RequestMapping(value = "/accounts/{accountId}", method = RequestMethod.PUT)
public ResponseEntity<?> createAccount(#PathVariable("accountId") Integer accountId,
#RequestBody Account acct){ ... }
My generated documentation using Swagger UI shows everything find however is unable to generated Model json for Account which is my model class.
Account is composed of few variables, in addition to an array of User Defined class 'Sharing'.
It is composed of another User defined class User.
Account class is annotated as follows:
#XStreamAlias("Account")
#XmlRootElement(name = "Account")
public class Account {... }
The generated documentation displays for Model Response and Request
**{
"unknownFields": {}
}**
Kindly guide as to what may be going wrong here. How to have a json version of Account object displayed. Thank you.
Well, the same thing worked on a next day. Not sure why it was not working on day one. Its appears idiotic but only purpose of me writing this is to ensure that nobody else doing the right way and gets confused with my post.

Is it possible to place variables into a resource path within a sling servlet?

We are trying to provide a clean URI structure for external endpoints to pull json information from CQ5.
For example, if you want to fetch information about a particular users history (assuming you have permissions etc), ideally we would like the endpoint to be able to do the following:
/bin/api/user/abc123/phone/555-klondike-5/history.json
In the URI, we would specifying /bin/api/user/{username}/phone/{phoneNumber}/history.json so that it is very easy to leverage the dispatcher to invalidate caching changes etc without invalidating a broad swath of cached information.
We would like to use a sling servlet to handle the request, however, I am not aware as to how to put variables into the path.
It would be great if there were something like #PathParam from JaxRS to add to the sling path variable, but I suspect it's not available.
The other approach we had in mind was to use a selector to recognise when we are accessing the api, and thus could return whatever we wanted to from the path, but it would necessitate a singular sling servlet to handle all of the requests, and so I am not happy about the approach as it glues a lot of unrelated code together.
Any help with this would be appreciated.
UPDATE:
If we were to use a OptingServlet, then put some logic inside the accepts function, we could stack a series of sling servlets on and make the acceptance decisions from the path with a regex.
Then during execution, the path itself can be parsed for the variables.
If the data that you provide comes from the JCR repository, the best is to structure it exactly as you want the URLs to be, that's the recommended way of doing things with Sling.
If the data is external you can create a custom Sling ResourceProvider that you mount on the /bin/api/user path and acquires or generates the corresponding data based on the rest of the path.
The Sling test suite's PlanetsResourceProvider is a simple example of that, see http://svn.apache.org/repos/asf/sling/trunk/launchpad/test-services/src/main/java/org/apache/sling/launchpad/testservices/resourceprovider/
The Sling resources docs at https://sling.apache.org/documentation/the-sling-engine/resources.html document the general resource resolution mechanism.
It is now possible to integrate jersy(JAX-RS) with CQ. We are able to create primitive prototype to say "Hello" to the world.
https://github.com/hstaudacher/osgi-jax-rs-connector
With this we can use the #PathParam to map the requests
Thanks and Regards,
San
There is no direct way to create such dynamic paths. You could register servlet under /bin/api/user.json and provide the rest of the path as a suffix:
/bin/api/user.json/abc123/phone/555-klondike-5/history
^ ^
| |
servlet path suffix starts here
then you could parse the suffix manually:
#SlingServlet(paths = "/bin/api/user", extensions = "json")
public class UserServlet extends SlingSafeMethodsServlet {
public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
String suffix = request.getRequestPathInfo().getSuffix();
String[] split = StringUtils.split(suffix, '/');
// parse split path and check if the path is valid
// if path is not valid, send 404:
// response.sendError(HttpURLConnection.HTTP_NOT_FOUND);
}
}
The RESTful way to approach this would be to have the information stored in the structure that you want to use. i.e. /content/user/abc123/phone/555-klondike-5/history/ would contain all the history nodes for that path.
In that usage. you can obtain an out of the box json response by simply calling
/content/user/abc123/phone/555-klondike-5/history.json
Or if you need something in a specific json format you could use the sling resource resolution to use a custom json response.
Excited to share this! I've worked ~ a week solving this, finally have the best Answer.
First: Try to use Jersey
The osgi-jax-rs-connector suggested by kallada is best, but I couldn't get it working on Sling 8. I lost a full day trying, all I have to show for it are spooky class not found errors and dependency issues.
Solution: The ResourceProvider
Bertrand's link is for Sling 9 only, which isn't released. So here's how you do it in Sling 8 and older!
Two Files:
ResourceProvider
Servlet
The ResourceProvider
The purpose of this is only to listen to all requests at /service and then produce a "Resource" at that virtual path, which doesn't actually exist in the JCR.
#Component
#Service(value=ResourceProvider.class)
#Properties({
#Property(name = ResourceProvider.ROOTS, value = "service/image"),
#Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
})
public class ImageResourceProvider implements ResourceProvider {
#Override
public Resource getResource(ResourceResolver resourceResolver, String path) {
AbstractResource abstractResource;
abstractResource = new AbstractResource() {
#Override
public String getResourceType() {
return TypeServlet.RESOURCE_TYPE;
}
#Override
public String getResourceSuperType() {
return null;
}
#Override
public String getPath() {
return path;
}
#Override
public ResourceResolver getResourceResolver() {
return resourceResolver;
}
#Override
public ResourceMetadata getResourceMetadata() {
return new ResourceMetadata();
}
};
return abstractResource;
}
#Override
public Resource getResource(ResourceResolver resourceResolver, HttpServletRequest httpServletRequest, String path) {
return getResource(resourceResolver , path);
}
#Override
public Iterator<Resource> listChildren(Resource resource) {
return null;
}
}
The Servlet
Now you just write a servlet which handles any of the resources coming from that path - but this is accomplished by handling any resources with the resource type which is produced by the ResourceProvider listening at that path.
#SlingServlet(
resourceTypes = TypeServlet.RESOURCE_TYPE,
methods = {"GET" , "POST"})
public class TypeServlet extends SlingAllMethodsServlet {
static final String RESOURCE_TYPE = "mycompany/components/service/myservice";
#Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
final String [] pathParts = request.getResource().getPath().split("/");
final String id = pathParts[pathParts.length-1];
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try {
out.print("<html><body>Hello, received this id: " + id + "</body></html>");
} finally {
out.close();
}
}
}
Obviously your servlet would do something much more clever, such as process the "path" String more intelligently and probably produce JSON.