Displaying spring #controller provided rest services in a jsp file - spring

I currently have a group of rest services provided by Spring 3.1.0 #Controller and wondered if there was any way that I could easily provide a list of the services (links to the restful services) in my index.jsp file. I know reflection is an option but thought spring may have a way to see the services provided by #Controller and allow me to display them.

Depending on the specific implementation of the HandlerMapping interface that your DispatcherServlet is using, you may be able to figure it out from there.
For example, if you are using the SimpleUrlHandlerMapping, there is a method present called getUrlMap(), which returns a map of the url path mappings.

What nicholas is pointing out is that there are different ways to maps requests. You've to check which HandlerMapping you're using exactly and then see how to get the mapping information it stores via class getters.
Here is an example for Spring MVC 3.1 #Controllers:
https://github.com/rstoyanchev/spring-mvc-31-demo/tree/master/src/main/java/org/springframework/samples/mvc31/endpointdoc

Related

Using #ConfigurationProperties statically - such as on #RequestMapping

Let's ignore for a moment whether doing this is a great idea, but I'm creating Spring Boot AutoConfiguration for an internal library and as part of this I want to auto-register a Controller that accepts GET/POST/DELETE requests (it is responsible for setting/clearing a cookie value for application testing purposes)
The issue is that I would like the request mapping path to be configurable by the end user. I have a #ConfigurationProperties(prefix = "my.configs") class that contains all the configuration values with their defaults for example: private String path = "default-path"
Ideally i'd be able to reference this in my controller like so: #RequestMapping(path=${my.configs.path}) but this does not work, Spring reports that it is unable to find that configuration parameter, if I place it into a properties file instead of into a the type-safe #ConfigurationProperties it works as expected.
I know I could get around this by putting a default value into the Request mapping, but I'd like to understand just what is happening here, and why I cannot statically refer environment variables read / defaulted into #ConfigurationProperties in the way that I can those defined in files.
#RequestMapping is a Spring MVC annotation and it gets processed by Spring MVC - no matter if it is all wrapped in Spring Boot app or not.
#ConfiguationProperties is on the other hand 100% Spring Boot code and to my knowledge both types of properties are processed at different moments during Spring Context startup lifecycle.

Servlets in spring mvc

I have fundamental idea about servlet and spring mvc. But I don't know that there is a usage of servlets in spring mvc or not. In spring mvc we have controller classes. My thinking is servlet is used in spring mvc as a controller. If I'm incorrect please correct me.
Yes,you are perfectly right. Servlets are used in Spring-MVC. In Spring-MVC when you write annotation like #Controller, indirectly you are using a Servlet called Dispatcher Servlet. Dispatcher Servlet is defined in web.xml file with properties and class name which is mapped to .jsp pages and Controller part.
Related / Duplicated to When to use Servlet or #Controller. The question is not the same but quite the explanation on that question you will be able to understand:
If you're a student interested in learning the language then I would stick with servlets for now. It's possible to write a web app using just servlets but in practice you'll probably want to look at JSP's too.
A JSP is a convenient way to write a servlet that allows you to mix html with scripting elements (although it's recommended to avoid Java code in your jsp in favour of tags and el expressions). Under the covers it will be compiled as a servlet but it avoids you having to use lots of messy print statements.
It's important to have at least a basic understanding of servlets and JSP's. Spring MVC is one of many frameworks built on top of servlets to try make the task of writing a web application a bit easier. Basically all requests are mapped to the DispatcherServlet which acts as a front controller.
The DispatcherServlet will then call the controller whose annotations match the incoming request. This is neater than having to write these mappings yourself in the web.xml (although with servlet 3.0 you can annotate servlets now). But you also get many other benefits that can be used like mapping form fields to an object, validating that object with jsr303 annotations, map inputs and outputs to xml or json etc etc. Plus it's tightly integrated with core spring so you can easily wire in your services for the controller to call.
It's worth noting that there are a plethora of competing frameworks built on top of servlets. Spring MVC is one of the most popular so it's not a bad choice to look into.
Controllers are not Servlets! Controllers are normal Spring MVC beans that do not extend HttpServlet. Instead what Spring has is a custom extension of HttpServlet called DispacherServlet. Looking at the DispacherServlet's source code you can see that the class hierarchy goes: DispatcherServlet extends FrameworkServlet → FrameworkServlet extends HttpServletBean → HttpServletBean extends HttpServlet.
The DispatcherServlet, like any other Servlet, is declared in the web.xml. It handles all incoming HTTP requests. It is called a front controller which provides a single point of entry in your application. It is responsible for request handling by delegating requests to additional components of Spring MVC controllers which do not extend the HTTP Servlet API.
Look at the following diagram
In this picture DispacherServlet is the only HttpServlet. The Controllers, HandlerMapping and ViewResolver are all Spring MVC beans.

When to use #RestController vs #RepositoryRestResource

I have been looking at various examples of how to use Spring with REST. Our end target is a Spring HATEOAS/HAL setup
I have seen two distinct methods for rendering REST within Spring
Via #RestController within a Controller
Via #RepositoryRestResource within a Repository
The thing I am struggling to find is why would you use one over the other. When trying to implement HAL which is best?
Our database backend is Neo4j.
Ok, so the short story is that you want to use the #RepositoryRestResource since this creates a HATEOAS service with Spring JPA.
As you can see here adding this annotation and linking it to your Pojo you have a fully functional HATEOAS service without having to implement the repository method or the REST service methods
If you add the #RestController then you have to implement each method that you want to expose on your own and also it does not export this to a HATEOAS format.
There is a third (and fourth) option that you have not outlined, which is to use either #BasePathAwareController or #RepositoryRestController, depending on whether you are performing entity-specific actions or not.
#RepositoryRestResource is used to set options on the public Repository interface - it will automatically create endpoints as appropriate based on the type of Repository that is being extended (i.e. CrudRepository/PagingAndSortingRepository/etc).
#BasePathAwareController and #RepositoryRestController are used when you want to manually create endpoints, but want to use the Spring Data REST configurations that you have set up.
If you use #RestController, you will create a parallel set of endpoints with different configuration options - i.e. a different message converter, different error handlers, etc - but they will happily coexist (and probably cause confusion).
Specific documentation can be found here.
Well, above answers are correct in their context still I am giving you practical example.
In many scenarios as a part of API we need to provide endpoints for searching an entity based on certain criteria. Now using JPA you don't have to even write queries, just make an interface and methods with specific nomenclature of Spring-JPA. To expose such APIs you will make Service layer which would simply call these repository methods and finally Controllers which will expose endpoints by calling Service layer.
What Spring did here, allow you to expose these endpoints from such interfaces (repositories) which are generally GET calls to search entity and in background generates necessary files to create final endpoints. So if you are using #RepositoryRestResource then there is no need to make Service/Controller layer.
On the other hand #RestController is a controller that specifically deals with json data and rest work as a controller. In short #Controller + #ResponseBody = #RestController.
Hope this helps.
See my working example and blog for the same:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with-hibernate-no-controller
#RepositoryRestController override default generated Spring Data REST controllers from exposed repository.
To take advantage of Spring Data REST’s settings, message converters, exception handling, and more, use the #RepositoryRestController annotation instead of a standard Spring MVC #Controller or #RestController
E.g this controllers use spring.data.rest.basePath Spring Boot setting as base path for routing.
See Overriding Spring Data REST Response Handlers.
Be aware of adding #ResponseBody as it is missed in #RepositoryRestController
If you not exposed repository (marked as #RepositoryRestResource(exported = false)), use #BasePathAwareController annotation instead
Also be aware of bags
ControllerLinkBuilder does not take Spring Data REST's base path into account and #RequestMapping shouldn't be used on class/type level
and
Base path doesn't show up in HAL
Workaround to fix link: https://stackoverflow.com/a/51736503/548473
UPDATE: at last I prefer not to use #RepositoryRestController due to lot of workarounds.

How can I include/exclude certain controllers from a DispatcherServlet

I have a DispatcherServlet which by default uses a RequestMappingHandlerMapping to find all controllers with #RequestMapping annotations.
This works fine, except that it picks up all controllers in my spring context, but I only want it to expose certain controllers.
Is there any way of doing this that doesn't involve extending a bunch of spring classes?
(Unfortunately my spring context has to contain these additional controllers as they also provide some functionality that I need to call using java, and I'm not able to split these up currently)
You can configure include/exclude filters to customize classpath scanning. This can be done both in XML Spring config or Java based #Configuration. So depending on how many #Controller annotated classes you need to exclude, you can either list them under assignable or use regex filter. See Spring docs section "Using filters to customize scanning" for details, e.g. for Spring 3.2.

What is good practice to configure Spring MVC application with Spring security?

Assume I have Spring MVC powered application with Spring security. I have:
UserBean class which provides CRUD operations on table User
UserController : controller which expose operation on User to http clients
UserLogin: Authentication provider from Spring security, which authenticates users.
How should I configure my application if:
I want simple XML configuration, with auto-discovering beans by annotations (<context:component-scan base-package="org.example"/>)
UserLogin and UserController needs UserBean to work
UserLogin and UserController use transaction annotations and aspect annotations
I see the following oportunities:
Create one common Spring XML configuration file, used both by DispatcherServlet and ContextLoaderListener
Disadvantage: nobody shows that solution in tutorial. All beans are duplicated (one instance in ContextLoaderListener context, second in DispatcherServlet). Duplication may cause some hard to track bugs. Duplication is not elegant
Create two Spring XML configuration files, one for ContextLoaderListener (main) and one for DispatcherServlet (controllers). UserBean is declared in first config and visible in second one
Disadvantage: to avoid duplication I have to add complex component scanning rules to both files (context:component-scan). <tx:annotation-driven and <aop:aspectj-autoproxy/> must be defined in both files. I will have still doubts which config file is appropiate when declaring new stuff.
Create two Spring XML configuration files and include third for common settings like <tx:annotation-driven
Disadvantage: I wanted simple solution...
Summary: I'm looking for good practice to configure application with Spring MVC + Spring Security AND security part is highly connected with business part. I was searching for good example but I always find case when security code is isolated from business code. But I need example when security and business share the code
Similar question: ContextLoaderListener or not?
I have two xml files for my configuration, no particular reason, that's just how it worked out.
These sample spring security projects provide good examples of lots of different types of configurations maybe you can find something that works for you:
https://github.com/spring-projects/spring-security/tree/master/samples
Hidden message in my question was: having two contexts is stupid.
Did someone already notice that?
Is there a way to have single application configuration?
Answers:
Yes. https://jira.springsource.org/browse/SPR-6903
Yes. https://github.com/michaldo/spring-single-context-demo
The best practice which applies to my case is described here: https://stackoverflow.com/a/14032213/2365727

Resources