I'm trying to write REST server, using this video example (careful, russian speech).
In the example, when lecturer writes #RequestMapping above controller class, class becomes in use. But in my case, controller class "is never used", and when I started tomcat server with my controller and going on page http://localhost:8000/app/remind/get , I get this error: No mapping for GET /app/remind/get
This is my controller code:
#Controller
#RequestMapping("/reminder")
public class ReminderController {
#RequestMapping(value = "/get", method = RequestMethod.GET)
#ResponseBody
public String getReminder(){
return "my reminder";
}
}
And this is my WebConfig.java
#Configuration
#EnableWebMvc
#ComponentScan("com.fillooow.remindme.server")
public class WebConfig extends WebMvcConfigurerAdapter {
}
So, can you explain, why my class "is never used" and what am I missing?
EDIT
My problem was wrong context in configuration file ("/" instead of "/app")
Suggestion: try #GetMapping; be sure you're using the correct URL:
#Controller
#RequestMapping("/reminder")
public class ReminderController {
#GetMapping(value = "/get")
#ResponseBody
public String getReminder(){
return "my reminder";
}
}
... and ...
http://localhost:8000/app/reminder/get
ALSO: I'm not sure about your context root ("app") or your port ("8000" vs. "8080").
POSSIBLE ALTERNATIVE:
http://localhost:8080/reminder/get
ADDITIONAL SUGGESTION: Enable debugging
logging.level.org.springframework=DEBUG
Try the endpoint like as below
http://localhost:8000/reminder/get
Related
I'm setting up the controller to match all routes and return the built production React. While doing that I couldn't do GET APIs from http://localhost:8080/api/ (Return the blank screen of React) when the POST method works fine. Any suggestion on how to make React match all routes except "/api", please?
My Controller Code
#Controller
public class ClientForwardController {
#GetMapping(value = "/**/{path:[^\\.]*}")
public String forward() {
return "forward:/";
}
}
I have found a solution to this question.
I've added SwaggerController.java controller
#Controller
#RequestMapping("/docs")
public class SwaggerController {
#GetMapping
public String index() {
return "redirect:/swagger-ui/index.html";
}
}
The point is to override the
"/**" matching in the previous controller I wrote above in the question.
And with the API endpoints ("/api"), I had a mistake to put GetMapping("/") for that controller so it has to write ("/api/something/something/") to match [I wrote "/api/something/something"]. So all the problems were fixed.
Suppose you have a Spring MVC controller, something like this
#Controller
public class RestController {
#GetMapping(value = "/test")
public #ResponseBody Test getTestData(...) {
// console log path to controller: http://localhost:80/app/test
return testData;
}
}
Is it possible to log/print from inside the controller the url to it? In the example above the output would be something like https://localhost:80/app/test
Using .getRequestUrl from the servlet is not behaving correctly.
You can inject UriComponentsBuilder as parameter then use the method toUriString(). From the documentation, it is used to build a relative URI from the current request’s, this should work as your are expected Doc.
#Controller
public class RestController {
...
#GetMapping(value = "/test")
public #ResponseBody Test getTestData(UriComponentsBuilder ucb, ...) {
LOGGER.debug(ucb.toUriString());
// console log path to controller: http://localhost:80/app/test
return testData;
}
...
}
We have some already developed REST APIs in SpringBoot.
Now we want to prepend some text (version of API eg /v1/) to all the #RequestMapping.
Is there any way of doing this except prepending /v1/ to every #RequestMapping
example: Current RequestMapping /employess and /cars/1/driver
Need to build like this /v1/employess and /v1/cars/1/driver
You can use such property in your application.properties file:
server.servlet.contextPath=/v1
or you can have a base controller class and extend it with all your controller classes
#RestController
#RequestMapping(value = "${rest.api.version}")
public class MyAbstractController {
}
and store rest.api.version in your application.properties file.
You could do it in at least 2 ways.
Option 1: extend AbstractAnnotationConfigDispatcherServletInitializer as below:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[] { "/v1/*" };
}
}
Option 2: add a request mapping on class level on the controllers you want the version prepended as below
#RestController
#RequestMapping("/v1")
public class Controller {
}
I would go for option 1.
If you want to append every request with "/v1", You can do so by using #RequestMapping annotation at the class level, in this way all the incoming calls(which has "/v1" in it) will land in your controller
#RestController
#RequestMapping("/v1")
public class YourController {
}
I am using #RepositoryResource annotation on my Reposioptory interface with this code:
#RepositoryRestResource(collectionResourceRel = "rest", path = "rest")
public interface HoliDayRepository extends CrudRepository<HoliDayEntity, Integer> {
HoliDayEntity findOne(Integer id);
}
and i have alsoe added RequestMapping("rest) in controller class
#RestController
#RequestMapping("/rest")
public class DayController {}
but when i start spring boot application and try this link :http://localhost:8080/rest i got 404 error also while building application i have ResourceNotFoumd exceptions how should i manage these errors?
with spring boot you don't need to create your own controller; also make sure your web application mapping is different to the one you use for spring data, for example you can set in application.properties spring.data.rest.base-path: /api
Have a look at this example:
public interface PersonRepository extends JpaRepository<Person, UUID> {
List<Person> findByAddress(String address);
}
with just this code you should able to access spring data repositories here: http://localhost:8080/api and the person endpoint here http://localhost:8080/api/person
Have a look at this tutorial: https://spring.io/guides/tutorials/react-and-spring-data-rest/ or this example: https://github.com/Paizo/SpringBootCamelStreamsExample
You need a method which should be called when you hit your endpoint.
try below and also check spring example:
https://spring.io/guides/tutorials/bookmarks/
#Autowired
private HoliDayRepository holiDayRepository; //your repository to execute the query
#GetMapping(value = "/{id}")//you can use #RequestMapping(method = RequestMethod.GET, value = "/{holida}")
public ResponseEntity<HoliDayEntity > getHolidayById(#PathVariable("id") Integer id) {
HoliDayEntity holiDayEntityresponse = productOperations.getProductById(id);
return new ResponseEntity<>(holiDayEntityresponse , HttpStatus.OK);
}
EDIT:
As pointed by Gimby, this is not applicable when #RepositoryRestResource is used. Both the code and the tutorial attached are refering to creating new REST service by creating the controller
is there a way to access the httpRequest within a controller level #PreAuthorize annotation to obtain a PathVariable and use it for the expression inside the #PreAuthorize annotation?
I want to be able to do the following, where #somePathVariable would result in the actual value passed for the PathVariable:
#RequestMapping(value = "/{somePathVariable}/something")
#PreAuthorize("#someBean.test(#somePathVariable)")
public class SomeController { ... }
It also would be sufficient if i could access the HttpServletRequest and get the PathVariable manually.
Please note that this expression is at the controller level before answering. I'd appreciate any help!
So as #pvpkiran already commented. It's probably not possible to get the param the way i want. However his workaround with using a bean to access the PathVariables manually seems to work just fine.
#Component
#RequiredArgsConstructor
public class RequestHelper {
private final HttpServletRequest httpServletRequest;
/* https://stackoverflow.com/questions/12249721/spring-mvc-3-how-to-get-path-variable-in-an-interceptor/23468496#23468496 */
public Object getPathVariableByName(String name) {
final Map pathVariables = (Map) httpServletRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
return pathVariables.get(name);
}
}
and
#RequestMapping(value = "/{somePathVariable}/something")
#PreAuthorize("#someBean.test(#requestHelper.getPathVariableByName('somePathVariable'))")
public class SomeController { ... }
did the job. It's not perfect but it works. The other (prob. better) option is to use #PreAuthorize on method level.
Thanks for your help!