I have a Java project with various #RequestMapping annotations.I want to make a new project which can use this #RequestMapping,is that possible
Of course you can.
If I understand your question correctly, do you want to use the data provided by a Spring application in another application?
It's not that hard, you just have to keep a few things in mind.
The applications have to run on different ports, of course both applications have to be started.
For example, App1 has a #RequestMapping #GetMapping for personal data.
The path is e.g. http://localhost:8080/persondata
In the second application, you only need to address the API endpoint if you need this data.
This can be done with RestTemplate, for example.
#RestController
#RequestMapping("/persondata")
class PersonDataRestController {
private final Service personService;
public PersonDataRestController(Service personService) {
this.personService = personService;
}
#GetMapping
public ResponseEntity<Collection<?>> getAllPersonData() {
return ResponseEntity.ok(personService.allPersonData());
}
}
You just have to replace the Service with your PersonService or whatelse.
in the second application you can call the REST endpoint with RestTemplate for example
RestTemplate template = new RestTemplate();
try{
ResponseEntity<ArrayList<?>> response = template.exchange("http://localhost:8080/persondata", HttpMethod.GET, null, new ParameterizedTypeReference<ArrayList<?>>() {});
In terms of the specific application, you may need a DTO object.
For this topic i can suggest you this website
I hope I could answer your question
Related
I'm used to developing in C# Web API where as well as routing attributes for individual endpoints I can also add a prefix for the controller, e,g,
[RoutePrefix("/MyController")]
However I'm developing in Java Spring Boot and although I can map individual endpoints, I can't find a way to add a prefix for all.
Is this possible?
On spring-boot you can use the #RequestMapping("/MyController") annotation at the class level.
#RequestMapping("/MyController")
public class MyController {
#GetMapping(value = "/helloWord") // this will become /MyController/helloWord
public String helloWorld() {
return "Hello World";
}
}
I have a REST API outside of my control (supplied by a different, distant team) which I need to consume from a Spring Boot application.
Currently I would like to write a test for that the request (not response) resulting from my RestTemplate invocation corresponds exactly to what is expected at the remote end. I have a sample JSON snippet that I would like to replicate from my code - given the same parameters as in the sample I should get an equivalent JSON snippet in the request body which I would then like to analyze to be certain.
My idea so far is to get RestTemplate to use a server under my control which then captures the JSON request. Apparently MockRestServiceServer is a good choice for this.
Is this the right approach? How do I configure MockRestServiceServer to allow me to do this?
If you're only interested in verifying the JSON mapping, you can always use Jackson's ObjectMapper directly and verify if the object structures match by using a library like JSONassert to verify if the serialized string matches your expected result. For example:
#Autowired
private ObjectMapper objectMapper;
private Resource expectedResult = new ClassPathResource("expected.json");
#Test
public void jsonMatches() {
Foo requestBody = new Foo();
String json = objectMapper.writeValueAsString(requestBody);
String expectedJson = Files
.lines(expectedResult.getFile())
.collect(Collectors.joining());
JSONAssert.assertEquals(expectedJson, json, JSONCompareMode.LENIENT);
}
This test purely uses ObjectMapper to verify the JSON mapping and nothing else, so you could even do this without actually having to bootstrap Spring boot within your test (which could be faster). The downside of this is that if you're using a different framework than Jackson, or if RestTemplate changes its implementation, that this test could become obsolete.
Alternatively, if you're interesting in verifying that the complete request matches (both URL, request method, request body and so on), you can use MockRestServiceServer as you mentioned. This can be done by adding the #SpringBootTest annotation to your test, autowiring RestTemplate and the service that invokes RestTemplate for example:
#RunWith(SpringRunner.class)
#SpringBootTest
public class FooServiceTests {
#Autowired
private RestTemplate restTemplate;
#Autowired
private FooService fooService; // Your service
private MockRestServiceServer server;
#Before
public void setUp() {
server = MockRestServiceServer.bindTo(restTemplate).build();
}
}
You can then set up your tests by using:
#Test
public void postUsesRestTemplate() throws IOException, URISyntaxException {
Path resource = Paths.get(getClass().getClassLoader().getResource("expected-foo.json").toURI());
String expectedJson = Files.lines(resource).collect(Collectors.joining());
server.expect(once(), requestTo("http://example.org/api/foo"))
.andExpect(method(HttpMethod.POST))
.andExpect(MockRestRequestMatchers.content().json(expectedJson))
.andRespond(withSuccess());
// Invoke your service here
fooService.post();
server.verify();
}
As per the documentation, you could match requests using json paths on Mock. For example;
RestTemplate restTemplate = new RestTemplate()
MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build();
server.expect(ExpectedCount.once(), requestTo(path))
.andExpect(method(HttpMethod.POST))
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].someField").value("some value"))
Note: I haven't tested this.
But I have achieved what you are looking for using Wire Mock many times. That's again a much better option than MockRestServiceServer. Why do I say so?
wide adoption and support
more elegant and extensive request & response matching
highly configurable
record and playback
configurable security/auth
you could even dockerise this
Have a look at http://wiremock.org/docs/request-matching/
I think your approach using a stub server (you could use WireMock for this) is fine if you want to check once, manually.
Alternatively you could add a request logger to your RestTemplate which logs each request. That would make it easier to check if the sent request is correct any time if problems arise.
I am using Jhipster(Angular + Springboot) Application for my existing project.
I managed to create a controller(app.resource) manually apart from the ones already generated by jhiptser(using .jh file) for achieving a file download functionality.
So, when we start the server we usually initiate two servers i.e gradlew and npm start. The second runs on port 9000 which eventually supports hot reload functionality.(front-end development)
So the problem is, I am able to access those endpoints from the server running on standard 8000 port. However, from the port which is a proxy(9000), the method is returning 404.
I tried to clean build the application several times.
NOTE: The #RequestMapping value on the new controller is different then those present already.
Does this have to do something with spring security?
Thanks in advance.
Here is the previous controller:
#RestController
#RequestMapping("/api")
public class FGAppDiagramResource {
#GetMapping(value = "/fg-app-diagram-downloadFile")
public void getImage(String fileName,String folderName, HttpServletResponse
response){
// Some Code
}
}
Here is my New controller:
#RestController
#RequestMapping("/fileDownload")
public class DownloadFileController {
private final Logger log =
LoggerFactory.getLogger(DownloadFileController.class);
public DownloadFileController() {
super();
}
#Autowired
private ApplicationProperties applicationProperties;
#GetMapping(value = "/fg-app-diagram-downloadFile/{fileName}/{folderName}")
public void getImage(#PathVariable String fileName,#PathVariable String folderName, HttpServletResponse response) {
// Some Code
}
}
Your new controller does not use /api so you must add your endpoint URL /fileDownload to proxy configuration of webpack dev server in webpack/webpack.dev.js
proxy: [{
context: [
/* jhipster-needle-add-entity-to-webpack - JHipster will add entity api paths here */
'/api',
'/fileDownload',
You may want to use /api/fileDownload to avoid changing proxy configuration and also because /api is useful for many other aspects like security and also using HTML5 URL routing strategy in Angular to get rid of # in client routes (see https://github.com/jhipster/generator-jhipster/pull/9098).
/api and /management are namespaces to avoid route conflicts, so it is usually wise to use them for your new endpoints.
I am new to Spring 3.1.0, and am trying to create an application, which can be exposed as a web application as well as web services.
For a POST where i am submitting a form object using the #ModelAttribute. I also want to expose this method which can consume the same object as XML, through any poster.
Shall i use both #ModelAttribute & #RequestBody together. I have already added the consumes property in the #RequestMapping annotation.
When you submit form, data comes in form-encoded manner, and when you use XML/JSON it comes as a string in body. You'd better place all your common logic to intermediate service layer and call it in your controllers. As a result it allows you to simply build REST services on top of existing HTML pages with forms:
public class Service {
public void registerUser(User user){
}
}
#RequestMapping("users")
public class FormController{
#Autowired private Service service;
#RequestMapping("register")
public ModelAndView registerUser(#ModelAttribute User user){
service.registerUser(user);
}
}
#RequestMapping("service/v1")
public class RESTController{
#Autowired private Service service;
#RequestMapping("users/register")
public ModelAndView registerUser(#RequestBody User user){
service.registerUser(user);
}
}
Actually, you can even put this in one controller.
I want the client and server application to talk to each other using REST services. I have been trying to design this using Spring MVC. I am looking for something like this:
Client does a POST rest service call saveEmployee(employeeDTO, companyDTO)
Server has a similar POST method in its controller saveEmployee(employeeDTO, companyDTO)
Can this be done using Spring MVC?
Yes, this can be done. Here's a simple example (with Spring annotations) of a RESTful Controller:
#Controller
#RequestMapping("/someresource")
public class SomeController
{
#Autowired SomeService someService;
#RequestMapping(value="/{id}", method=RequestMethod.GET)
public String getResource(Model model, #PathVariable Integer id)
{
//get resource via someService and return to view
}
#RequestMapping(method=RequestMethod.POST)
public String saveResource(Model model, SomeResource someREsource)
{
//store resource via someService and return to view
}
#RequestMapping(value="/{id}", method=RequestMethod.PUT)
public String modifyResource(Model model, #PathVariable Integer id, SomeResource someResource)
{
//update resource with given identifier and given data via someService and return to view
}
#RequestMapping(value="/{id}", method=RequestMethod.DELETE)
public String deleteResource(Model model, #PathVariable Integer id)
{
//delete resource with given identifier via someService and return to view
}
}
Note that there are multiple ways of handling the incoming data from http-request (#RequestParam, #RequestBody, automatic mapping of post-parameters to a bean etc.). For longer and probably better explanations and tutorials, try googling for something like 'rest spring mvc' (without quotes).
Usually the clientside (browser) -stuff is done with JavaScript and AJAX, I'm a server-backend programmer and don't know lots about JavaScript, but there are lots of libraries available to help with it, for example see jQuery
See also:
REST in Spring 3 MVC
Yes, Rest is very easy to implement using spring MVC.
#RequestMapping(value="/saveEmploee.do",method = RequestMethod.POST)
#ResponseBody
public void saveEmployee(#RequestBody Class myclass){
//saving class.
//your class should be sent as JSON and will be deserialized by jackson
//bean which should be present in your Spring xml.
}