Testing Forwarding in a Spring MVC App - spring

Is there any way of testing the functionality of a forward:/ view being returned from a Spring MVC controller in a JUnit test?
I'm using the MockMvc functionality from Spring 3.2 and my controller under certain circumstances forwards to another (by means of returning a view name of forward:/pathHandledByController).
It'd be great to be able to assert that when this forwarding has taken place, all the #ModelAttributes from the second controller are applied and everything processes properly. Unfortunately MockMvc only lets me assert that the view name returned started with forward:/.
Is there any way I can test this without spinning up the whole web-app in something like Jetty? I've got lots of services plumbed into the MVC application, how would I create a web-app that uses separate Spring config (from src/test/resources) with mocks of these services?

You can use forwardedUrl matcher:
mockMvc.perform(get("/controller/path"))
.andExpect(forwardedUrl("/forwarded/url"));

Related

Adding a REST API to Spring MVC application

Assuming an application with a traditional UI based on Spring MVC and Thymeleaf, it seems like there are a few ways to expose a REST API...
Add a completely separate set of Controllers using #RestController - Feels like a lot of duplication, but allows complete separation of UI vs REST logic
Use a single Controller for each entity, with a mix of both #ResponseBody methods and ModelAndView methods - Keeps all logic for a given entity in a single place, but requires mixing different concepts
Use a single Controller for each entity, use only ModelAndView, and use content negotiation with a JSON view resolver like the MappingJackson2JsonView (https://spring.io/blog/2013/06/03/content-negotiation-using-views/)
I'm particularly interested in #3 as it feels similar to how Ruby on Rails Controllers work with the respond_to for different content types.
Is this a common approach / best-practice in Spring applications?
Would POST and DELETE requests still require separate methods since they may work differently between a REST API vs the UI? (i.e. posting a form vs posting a json entity)
Would it require separate Exception handling based on whether it was a UI request or API request?
I'd go with option 1. Having a separate set of #Controller and #RestController avoids mixing MVC pattern with your REST api. To avoid code duplication, you should add a service layer and have the REST endpoint and the MVC controller to make use of that service layer.

Spring Boot REST architecture

Lately i've been developing a Spring boot application with Angular 5 frontend and i got a little confused about the architecture of it. I was taught to write repositories, services and controllers in spring and to follow the MVC pattern. I started to write the documentation for the app and im trying to describe the arhitecture. So as i think View is the Angular app, C consists of the controller classes, and i described the third layer as buisniss logic which consists of the entity and service classes. But what is the Model really? Did i manage to follow the MVC pattern? In addition i have a controlleradvice, exception classes and security classes that make the authentication and authorization using jwts, but i guess these classes totally stay out from the MVC.
I've searched for the explanation but didnt seem to find it. Could someone please explain this to me? Thank you!
UPDATE
So basically what i dont understand is how the spring classes + angular meet the requirements of the MVC pattern
For example this is one of the first diagrams on the internet when you search for spring layers but as i see these are different from MVC
enter image description here
As mentioned in the comments, both your backend with Spring boot and your frontend with Angular can be seen as different applications, each following the Model-View-Controller design pattern.
You also posted a screenshot of the three-tier architecture. This type of architecture only tells you about how to structure your code. Typically, the MVC-part of your application is within the presentation layer (in your screenshot it's called the web layer).
So, if you would look at your backend application, you can identify the following parts:
Data tier/Repository layer: Repositories
Business tier/Service layer: Services
Presentation tier/Web layer: Model-View-Controller + Dispatcher
Model: Whatever you expose within your services (could be DTOs)
View: JSON structure/mapping
Controller: Spring controllers
And for your frontend you could identify them as well:
Data tier: HTTP calls
Business tier: Angular services
Presentation tier: Components + Router
Model: Whatever you expose within your services (probably a similar structure as the one you expose in your backend)
View: Templates
Controller: Components
This is a bit oversimplified though, and probably not something everyone will agree with.
I am working on the same project with angular as a frontend and spring boot as a backend, and i am still a little bit confused about it's architecture just like you, but i finally had to adopt the MVC model since i am actually using controllers, defining models and rendering views (the json results).
Obviously your front end uses a CBA (component based architecture and your backend is using an MVC pattern since spring MVC is embedded inside spring boot so it actually uses the same logic.
here's a brief image of how spring boot dispatches between controllers and handles requests, you can consider your dispatcher servlet as the middleware between your front end and your backend (but keep in mind that it is embedded inside the spring boot container)
Angular is an SPA, a single-page-application. It contains everything, Model (changing of business data), View (templates with HTML) and Controller (your click- and other event-handlers in your components).
The Spring backend is an extension of the Model, for performing further data transformation and storing it on a database.
The Model-View-Something (there is also MVVM and derivations) is a pattern that comes from desktop-applications, but it doesn't really fit in the world of SPAs. And the Controller in MVC is often seen as redundant even in desktop-applications (because it just delegates stuff and not taking as big role as View and Model).
Important for you to know when you work with Angular is rather the Component-pattern. It is valid in Angular, in React, Vue and even in Vaadin. A component is chunk of both HTML and script-code manipulating that HTML. And components can nest each other allowing a hierarchical architecture.

spring MVC forwarding request to another controller

I have few spring controllers all of these controller modelAttribtes are extended some commonForm(BaseForm). All common properties were in BaseForm and specific properties are in sub classes which acts as ModelAttributes for controllers.
Based on special condition I have scenarios to forward to another controller but while this forward is happening the request contains old data as well and giving double values to the parameters and failing the forwarded request.
Actually this code is copied from struts based project as part of migrating to spring MVC.
Please help me on this.
Thanks,
Syamala.

Seems like struts validate method doesn't work anymore when using spring

I am now moving to Struts for my presentation layer. I have done a simple example using Struts alone (not really, actually, I test an example inside a simple maven project). From now on, I am likely to use Struts with Spring so I try to migrate my simple application, my goal was to use service layer to deal with specific operation.
In my simple test, I extend action from Struts action, now that I am using Spring, I extend it from ActionSupport so that I can fully use spring injection. Now it seems like even though I override validate method, it is no longer called. Is that the right behaviour, if so, where should perform operations like checking if my mandatory fields are populated (inside action or service ?)
Thanks for your answer !

A heavily customized Spring Web application and the dispatcher servlet

We have a web application that uses spring, struts and camel right now and there is a lot of customization we have done to allow us to know when beans are added to the context.
So, we have gotten to a point where we would like to remove struts from the application, because we are only using it to handle actions and we figure we could either use spring or camel to do the same thing. So I was able to get it to work with camel/velocity, but we didn't like how we really couldn't use the request object directly in the jsp (afaik, you have to put everything in the header of the Exchange and in the jsp you would do ${header.someReqVariableName}).
So we wanted to go the spring route, but since we load the context.xml directly, we have a provider that extends ContextSingletonBeanFactoryLocator and we pass the xml file name as a param, we haven't been able to figure out how to get the DispatcherServlet to work without giving it another configuration xml.
Is there a way to either:
Have camel use jsp for processing a jsp (and have all the usage of jsp tags)?
or
Have spring to see that a context has already been loaded and use that instead of having another new one?
or
Something better I have thought up?
You can use camel-jetty to expose HTTP endpoints, but I wouldn't use it for any complex web app development (JPS, etc). I'd use use Spring MVC (or similar) and use Camel for any complex routing/messaging requirements...
Here is another way, you can use the producer template to send the request to the camel context if you can get the reference of the camel context from the spring.

Resources