We currently have a level 2 RESTful web service. We are updating the service to incorporate hypermedia support. We are using Spring Data Rest on the back-end to handle the setting of the HATEOAS properties. The problem we're having is that we still need to support our legacy API consumers until the migration can be completed, meaning we still need to support responses without HAL properties like "_links" and "_embedded".
For reasons that aren't really worth explaining, we cannot address this problem with URL versioning. We need instead to be able to map requests with an Accept header of "application/json" to our old controllers, and let SDR handle any requests with "application/hal+json". In essence, we'd like to use SDR as a fallback to handle API requests that are specifically requesting HAL-formatted responses.
I came across this excerpt in the SDR documentation:
We register a custom HandlerMapping instance that responds only to the
RepositoryRestController and only if a path is meant to be handled by
Spring Data REST. In order to keep paths that are meant to be handled
by your application separate from those handled by Spring Data REST,
this custom HandlerMapping inspects the URL path and checks to see if
a Repository has been exported under that name. If it has, it allows
the request to be handled by Spring Data REST. If there is no
Repository exported under that name, it returns null, which just means
"let other HandlerMapping instances try to service this request".
The Spring Data REST HandlerMapping is configured with
order=(Ordered.LOWEST_PRECEDENCE - 100) which means it will usually be
first in line when it comes time to map a URL path and your existing
application will never get a chance to service a request that is meant
for a Repository. For example, if you have a Repository exported under
the name "person", then all requests to your application that start
with "/person" will be handled by Spring Data REST and your
application will never see that request. If your Repository is
exported under a different name, however (like "people"), then
requests to "/people" will go to Spring Data REST and requests to
"/person" will be handled by your application.
This seems to imply that what we're trying to accomplish is possible, assuming the HandlerMapping order can be configured differently. I haven't been able to make that work so far though:
Setting SDR's HandlerMapping to Ordered.HIGHEST_PRECEDENCE seems to have no effect.
Setting SDR's HandlerMapping order to Ordered.LOWEST_PRECEDENCE seemed to disable ordering altogether, and my custom controllers did field the requests, but SDR was no longer responding to any requests. application/hal+json just resulted in a 406 status.
Is there any way to configure the HandlerMappings correctly such that my custom controllers take priority and SDR fields any requests not specifically mapped to my controllers?
Related
I want to create a REST API in spring boot which can handle around 100TPS. Lets say I create a basic REST api using a sample application in spring boot. Does this automatically handles multi threading. Lets consider the code bellow.
#RequestMapping(method = RequestMethod.POST, value="findByPackageActivationId")
#ResponseBody
public JSONObject findByPackageActivationId(#RequestBody IncomingRestObject incomingRestObject) {
//My work here
}
By default Spring Boot web applications are multi-threaded and will handle multiple requests concurrently.REST controller is multithreaded as the DisptcherServlet handles multiple requests from the clients concurrently and serves using the respective controller methods.You can change any of the default thread settings as well (e.g. server.tomcat.max-threads). For more information refer here :-
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc
REST controller is multithreaded as the DisptcherServlet handles multiple requests from the clients concurrently and serves using the respective controller method
You can scale your app as per your requirements to achive desired TPS
https://dzone.com/articles/how-to-test-if-your-multi-threaded-java-rest-servi
For every request from the client, the server will create a new thread and assign that request to newly created thread. You don't have to handle this explicitly.
Also for your requirement(100 Threads), you can configure this on the server. You can refer this link for tomcat configuration as its default server for spri.
Spring Framework provide these feature internally, these are benefits that spring provide over core servlet coding that we used to do in older days. It also provide the way to control it.
For Ex you can change limit of number of thread to create using server.tomcat.max-threads (For tomcat).
For Basic understading on multi threading with spring boot please refer https://www.e4developer.com/2018/03/30/introduction-to-concurrency-in-spring-boot/
Actually I am trying to understand the DispatcherServlet and came to know that it is following the FrontController Design Pattern.
While trying to understand the FrontController design pattern came across this link
FrontController from Oracle Doc reference
Not much understood as I am beginner, but few things I understood Like Below
If we don't have FrontController we often try to duplicate the code in multiple controller like authentication and Authorization. And because of which maintainability becomes a big issue if we want to change something in future. So having frontController in place we can move the basic functionality to frontController and changes can be done easily.
When I explained Same thing in the interview he asked me what are those basic functionalities. I told Internalization, viewResolver, Authentication, Authorization etc. And now again asked consider like there is no dispatcher Servlet how do you handle those functionalities in each controller?
Since am basically a Desktop Application developer I couldn't answer for his next question.
So here are my questions
Firstly, is my understanding correct?
If my understand is correct, how to answer for the second question of the Interviewer? Which is consider like if there is no dispatcher Servlet how do you handle those functionalities in each controller? means asked me to write some pseudo code of the common functionalities. Which I couldn't as I am swing developer. Could someone please explain me, with some sample code which we repeat across the controller and now with dispatcher we could avoid.
If we Start comparing DispatcherServlet with frontController Design Pattern can we say like LocaleResolver, HandlerMapping, ThemeResolver, ViewResolver, HandlerExceptionResolver, HandlerAdapter, MultipartResolver etc. are Helper classes for DispatcherServlet?
The front controller design pattern means that all requests that come for a resource in an application will be handled by a single handler and then dispatched to the appropriate handler for that type of request. The front controller may use other helpers to achieve the dispatching mechanism.
Front Controller design pattern could be implemented by either of following two ways.
Using Servlet
Using Filter
Spring Framework implemented FrontController Design Patter using DispatcherServlet for intercepting each request and delegate to responsible controller to process the request.
If interviewer asks you, what happened if you don't have DispatcherServlet then how you manage all these authentication and authorization things, you can simply say that I can define a Filter which will intercept each request. Filter should be responsible for dispatching,authentication and authorization thing. Struts uses Filter to implement FrontController Design pattern.
(1) FrontController is simply the central place where all the external requests are received by and pass each of those requests to the appropriate handler. As you have explained since this is the central place for all the requests, it can be used to perform all the common things like security, logging etc.
(2) DispatcherServlet is the actually the front controller of Spring MVC. It intercepts each request and then dispatches each to the appropriate controller which has been registered in Spring Application Context.
consider like if there is no dispatcher Servlet how do you handle
those functionalities in each controller ?
For this one, I don't think this question implies that you need to write same code in each controller. (If it does, it cannot be a good idea)
You can do something like implementing a separate service which would do those common things (cross cutting concerns) for you can orchestrate all in coming requests.
Front Controller Definition
The front controller is responsible for handling all the requests for
a website. For web application developers, it can be a very useful
structure, as it allows the developers the flexibility and the ability
to reuse the code without having to add again and again.It provides a single point of action to handle the all coming requests to the J2EE web application, it forwards the request to specific application controller to access model and view for presentation
tier resources.
lets check the functionality of the Dispatcher Servlet to see if it is exactly the front end:
Consider the diagram below taken from https://docs.spring.io/spring/docs/3.0.0.M4/reference/html/ch15s02.html:
As you can see in the preceding diagram, the front controller is introduced for the
MVC pattern. It is implemented as a javax.servlet.Servlet servlet such as ActionServlet in struts, FacesServlet in JSF, and DispatcherServlet in Spring MVC. It handles the incoming requests, and delegates the requests to the
specific application controller. That application controller creates and updates the model, and delegates it to the front controller for rendering. Finally, the Front Controller determines the specific view, and renders that model data.
Now Consider the step as:
A user clicks on the browser or submits a web form of the application. The
request leaves the browser, either with some additional information or with
common information. This request lands at Spring's DispatcherServlet, which is a
simple servlet class as other java-based web applications. It is a Front
Controller of the Spring MVC framework, and funnels all the incoming requests
through the single point. The Spring MVC framework centralizes the request
flow control by using this Front Controller.
A user clicks on the browser or submits a web form of the application. The
request leaves the browser, either with some additional information or with
common information. This request lands at Spring's DispatcherServlet, which is a
simple servlet class as other java-based web applications. It is a Front
Controller of the Spring MVC framework, and funnels all the incoming requests
through the single point. The Spring MVC framework centralizes the request
flow control by using this Front Controller.
Once a particular application controller is decided by Spring's DispatcherServlet
with the help of the handler mapping configuration, DispatcherServlet dispatches
that request to the selected controller. This is the actual controller responsiblefor processing information according to the user's request and its parameters.
Once a particular application controller is decided by Spring's DispatcherServlet
with the help of the handler mapping configuration, DispatcherServlet dispatches
that request to the selected controller. This is the actual controller responsiblefor processing information according to the user's request and its parameters.
Once a particular application controller is decided by Spring's DispatcherServlet
with the help of the handler mapping configuration, DispatcherServlet dispatches
that request to the selected controller. This is the actual controller responsiblefor processing information according to the user's request and its parameters.
Spring MVC's DispatcherServlet renders the model to the view, and generates a
user-readable format of the model's information
Finally, that information creates a response, and returns it to the user's browser
by DispatcherServlet.
So The Spring MVC module provides out-of-the-box front controller pattern implementation by introducing the org.springframework.web.servlet.DispatcherServlet class. This is a simple servlet class, and the backbone of the Spring MVC framework. And this Servlet is integrated with the Spring IoC container to benefit the Spring's dependency pattern. Spring's web framework uses Spring for its own configuration, and all controllers are Spring beans. you can see the spring doc https://docs.spring.io/spring/docs/3.0.0.M4/reference/html/ch15s02.html that admitted the usage of front controller design pattern in DispatcherServlet
Answers specifically to your questions:
yes your understanding is okay but for a better view refer to my description
when there is no DispatcherServlet you need to define something to take care of the functionality you need and the best thing is to write a filter including your logic of authentication and authorization
These are not refer as Helper classes as it has it's own definition in OOP, you can consider them components playing part in front controller design pattern implemented version of Spring
More Info:
Majority of the definition comes from the book Spring 5 Design Patterns by Dinesh Rajput, you can refer this book for more info
I have a class that extends JAX-RS' Application. Its ApplicationPath is currently "/", however this overrides all requests from the root, which sucks because I have a lot of other servlets listed in web.xml that I don't want to handle with REST. I'd like to gradually move these existing endpoints over to JAX-RS, but all examples I've seen would imply that I can't selectively handle endpoints like this without URL rewrite rules on the server.
I would like to move these endpoints as such without having to rename them, i.e. without having to change /stuff/list to /rest/stuff/list.
Is there any other way? I'm using RESTeasy as my provider. It has a resteasy.resources web.xml parameter option with which I can specify my resources manually, but an Application with an ApplicationPath is still needed.
I am attempting to set the X-Frame-Options to DENY for all management endpoints, particularly the /error endpoint. I have the following in my application.properties of my Spring Boot application.
security.headers.frame=true
management.security.enabled=true
management.port=8001
When I go to http://localhost:8001/error I do not have the X-Frame-Options header, however the http://localhost:8001/trace endpoint does have the header. How do I configure my application.properties or what do I need to override to get that response header for the error endpoint?
Going through the current Spring Boot source (1.1.7.RELEASE), I don't see anyway that you can do what you want without totally doing away with the Security auto-configuration.
That is because in order for an endpoint to be eligible for the customized HTTP Headers (like X-Frame-Options) it needs to be a bean in the parent context (the one that is associated with the application on the normal port) that implements MvcEndpoint. Such beans are HealthMvcEndpoint, JolokiaMvcEndpoint etc.
My statement adove can be viewed in code at ManagementSecurityAutoConfiguration in the ManagementWebSecurityConfigurerAdapter.configure method (endpointHandlerMapping is created from the MvcEndpoint implementation beans).
The error page for the management app, is ManagementErrorEndpoint that is created in errorEndpoint of EndpointWebMvcChildContextConfiguration which is triggered when the child context is created (due the inclusion of the management app), which is too late to be included in the endpoints that supported for HTTP Headers customization
The /error endpoint is not an Actuator Endpoint and it's not secured by default (lots of errors can happen when a user is not authenticated). You could maybe make it available to anonymous users, but my guess is not even that would prevent some nasty infinite loops, where there is a mistake in the security configuration. I'm sure there's another way to add the header without Spring Security?
I tried using Basic Authentication by changing the server.xml config of Tomcat 6.0 but it did not worked: BASIC authentication in jersey JAX-RS service and Tomcat 6.0 getting failed
Hence I am opting a way where no server specific config is needed and I can add up the roles directly in my code (either client or server; not sure about theavailable options).
Please provide me some ideas about the possible options for setting the user roles so that I can authenticate my Web Service methods using the #RolesAllowed annotation.
You need to go back and figure out why your security constraints weren't working. Maybe start with the default file realm before moving on to JDBC realms. #RolesAllowed in an annotation that triggers behavior in the container.
If you really want to do it yourself (a bad idea) they you'd probably start by creating a custom servlet filter that implemented the entire basic http challenge mechanism. Next you'd have to replace the SecurityContext provider in Jersey.
They "thing" that enables #RolesAllowed in jersey is this: http://java.net/projects/jersey/sources/svn/content/trunk/jersey/jersey-server/src/main/java/com/sun/jersey/api/container/filter/RolesAllowedResourceFilterFactory.java Which, by the way, don't forget to add as an init-param to your jersey servlet. The RolesAllowedResourceFilterFactory gets its security info from an injected SecurityContext which I'm sure at some point just delegates off to the Servlet API for credential info.
So basically if you don't want to take the time to get security constraints working you are going to end up replacing most of the chain...like I said, a bad idea.
The features on application servers are there to keep you from having to spend time creating infrastructure code, if you write your own infrastructure code you're going to have a bad time.