Class with #RequestMapping is never used - java

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

How to custom Java Spring GET match all routes except "/api" and "/swagger-ui"

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.

Log url to Spring controller from inside it

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;
}
...
}

How to prepend some text to all controller URL in Spring

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 {
}

Can't use ReposiotryResource endpoint in spring service

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 a PathVariable in a controller level #PreAuthorize annotation?

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!

Categories