Java Spring MVC stateless-to-stateful handover - java

Although I have tagged this as a java/spring question it can be easily asked of any mvc framework with stateless controllers. I know rails uses simple stateless controllers for instance so perhaps you guys know how to best solve this problem. I can best describe the problem with java/spring mvc which is the implementation - forgive the java jargon.
The issue
We are having trouble coming up with a satisfactory way of performing stateless-to-stateful handover in spring mvc.
In essence given a structure like:
Model: Unit
With the states: withdrawn, available, unavailable
And the operations: getOutline() and getHelp()
Controller: UnitController
with operations: displayOutline() and displayHelp()
We need a way to check the state of the unit before we execute the operation displayOutline() (because the unit itself may be withdrawn and so the user should be forwarded to a withdrawn page).
We have tried to do this a number of ways including:
The dead simple way (any language)
All methods in the controller that require an ‘available’ state unit call a method isAvailable() in the first line of its implementation. Obviously there lots of replication here, it reeks.
The AOP way (Java specific)
An #Around advice can be created called UnitAccess which does the check and reroutes the control flow (i.e. instead of calling proceed() which would invoke the underlying method it calls another method on the controller). This seems like a hack and not really what AOP if for, it does remove the replication but adds complexity and reduces transparency.
An Interceptor (Provided by servlet architecture but probably doable in other frameworks)
Which checks the unit state and essentially changes the actual URL call. Again this does not seem right. We don’t like the idea of invoking model logic before getting to a controller.
We have thought about
Command Pattern
Creating a command pattern structure which (with the use of inheritance) can return a withdrawn view or valid displayOutline view. As the execute method will perform the checks in a super()call and the specific logic inside the concrete commands. Ie creating a object structure like
DisplayOutlineCommand extends UnitCommand
public void execute(){
super();
// must be ok, perform getOutline()
}
And finally, using a custom Exception
Calling getAvailableUnit() on a service level object which will do the checks for availability, etc before returning the unit. If the unit is withdrawn then it will throw a UnitWithdrawnException which could be caught by the servlet and handled by returning an appropriate view. Were still not convinced. We are also not hot on the idea of using an exception for normal flow control.
Are we missing something? Is there an easy way to do this under spring/another stateless controller framework?

Maybe I'm missing the point, but why should a user come to the controller if the Unit is withdrawn?
I would argue it is best to ensure that normally pages don't link to a controller that require the Unit to be 'OK', if that Unit is not 'OK'.
If the state of the Unit changes between the time the referring page is rendered and the actual call comes in to the controller (it is not longer 'OK'), then the use of an exception to handle that event seems perfectly fine to me (like having an exception when an optimistic locking error occurs).

Perhaps you haven't described the whole problem, but why not put the check in displayOutline() itself? perhaps route to a displayOutlineOrHelp() method, which looks essentially like
ModelAndView displayOutlineOrHelp(...) {
Unit unit = ... //code to get the unit the request refers to
return unit.isAvailable() ? displayOutline(...) : displayHelp(...);
}

Related

Can ResponseEntity be used outside of Controllers in Spring?

I have the following question. I find myself in using ResponseEntity inside a RestController in Spring whenever I want to manipulate the HTTP response coming back from my controller.
Let's say now that the outcome of this response depends indeed on what happens on the business layer below. Let's say this layer makes an http call, if it goes right I forward back above a positive message, instead I forward a negative message.
My controller now receives a message, but it would be nice to analyze whetever what happened down below was successful or not. So, can I return from the business level a ResponseEntity and mark it already as 400 or 200 (depending on what happens down there) or there is another better practice?
Sure you can. Technically ResponseEntity is a class like any other, you can return an instance of it from any layer.
The question you should ask yourself though, is this a good practise to return object of that class from a method that suppose to perform some business logic? For me it does not feel right. You introduce layers to separate concerns. Your domain layer should be totally agnostic of off communication protocol your application offer.
If you design domain layer right you'll know what went wrong based on thrown exception. Then you'll also know which HTTP status you should return.
This violates the concept of separation of layers: It is the controller's only job, and only the controller's job, to translate between the language of HTTP and your application's internal language (API). What if, in the future, you want to change how your HTTP API works but support multiple versions at the same time?
Instead, this is exactly what exceptions are for: Throw a sensible exception from your business methods. I frequently create subclasses of exception types such as IllegalStateException to represent application-specific errors, and sometimes I use the existing exception classes directly.

Why use Spring's Mock MVC when you have unit tets of your controller classes

I have seen people around me using Spring MVC in unit tests for controller classes, which is not helpful in what a unit test is for.
Unit tests are supposed to test your actual implementation of the controller class, and this can be achieved more accurately with simple Junit tests rather than using Spring Mock MVC.
But then the question arises, what's the real usage of Spring Mock MVC then? What do you need it for?
Let's say I have below code :
#Controller
#RequestMapping("/systemusers")
public class SystemUserController
{
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String getUser(final Model model)
{
// some logic to return user's details as json
return UserDetailsPage;
}
}
I can test this class/controller more accurately with Junit than with Spring Mock MVC (all it does is generates some json which can be asserted with junit).
I can also test with Spring Mock MVC like using the correct endpoint returns the correct HTTP status and correct response page string.
But doesn't that mean that we are testing Spring MVC's functionality rather than the actual code for method under test?
P.S. : I have kept the code to minimal which I think is sufficient to explain my question. Assume there is no compilation error.
When it comes to the unit-testing of a Controller (or any Endpoint which is exposed) classes, there are two things that we will validate:
(1) Controller's actual logic itself as standalone i.e., right service calls are invoked or not etc..
(2) Request URL mapping and the Response status & object
Item (1) above is what we test in general with all other classes like Services, Utility classes etc..
Item (2) needs to be covered/tested additionally for the endpoints (controller classes) which have been exposed, so whether we use Spring's MockMVC or other machinery to do that, it is up to us really.
Spring's MockMVC indeed helps us to start the in-memory servlet container & check that the right controller methods are invoked & then the right responses have been coming out.
From my personal experience, testing the controllers (for item(2)) helped me to resolve URL mapping conflict issues (of course, within the same controller) etc.. straight away rather than fixing them at the later stages of the project.
Based on My experience I will try to answer your question.
First thing we need to understand why we use unit testing?
It is a extra check used by developer to write clean working code.
Clean working code means every line written should be doing what it is
expected to do. how do you achieve this? Here comes unit testing. The
standalone unit of code you are writing should be verified standalone.
Method is best part in code which represents standalone unit code
template.
Unit Testing for Method
Developer should write a test for method which describes the method
behavior. And possible checks that i follow is is it returning the
expected value considering all positive scenarios? is it working in
case of Exception? is it calling correct subsequent methods ?
Developer should verify the method by actually calling it providing a
mock environment
Below is possible answer to your question. though it is solely based upon the developers.
Controller methods are intended to invoke correct service call accepting input and returning the value from service to view.
So I may think of write a unit test case for controller method as you are thinking is a right approach. But you should verify the method by calling it in same way as it will be called in real time.
so you need to call controller method in same way as MVC does. Hence it is better option to use MockMVC.
MockMVC is also useful to verify the urls, input params , response and status which are part of controller method. Considering these all it makes it standalone unit of code.
Hope this will clarify your doubt.

Unit Testable convention for Service "Helper Classes" in DDD pattern

I'm fairly new to Java and joining a project that leverages the DDD pattern (supposedly). I come from a strong python background and am fairly anal about unit test driven design. That said, one of the challenges of moving to Java is the testability of Service layers.
Our REST-like project stack is laid out as follows:
ServiceHandlers which handles request/response, etc and calls specific implementations of IService (eg. DocumentService)
DocumentService - handles auditing, permission checking, etc with methods such as makeOwner(session, user, doc)
Currently, something like DocumentService has repository dependencies injected via guice. In a public method like DocumentService.makeOwner, we want to ensure the session user is an admin as well as check if the target user is already an owner (leveraging the injected repositories). This results in some dupe code - one for both users involved to resolve the user and ensure membership, permissions, etc etc. To eliminate this redundant code, I want make a sort of super simpleisOwner(user, doc) call that I can concisely mock out for various test scenarios (such as throwing the exception when the user can't be resolved, etc). Here is where my googling fails me.
If I put this in the same class as DocumentService, I can't mock it while testing makeOwner in the same class (due to Mockito limitations) even though it somewhat feels like it should go here (option1).
If I put it in a lower class like DocumentHelpers, it feels slightly funny but I can easily mock it out. Also, DocumentHelpers needs the injected repository as well, which is fine with guice. (option 2)
I should add that there are numerous spots of this nature in our infant code base that are untestable currently because methods are non-statically calling helper-like methods in the same *Service class not used by the upper ServiceHandler class. However, at this stage, I can't tell if this is poor design or just fine.
So I ask more experienced Java developers:
Does introducing "Service Helpers" seem like a valid solution?
Is this counter to DDD principals?
If not, is there are more DDD-friendly naming convention for this aside from "Helpers"?
3 bits to add:
My googling has mostly come up with debates over "helpers" as static utility methods for stateless operations like date formatting, which doesn't fit my issue.
I don't want to use PowerMock since it breaks code coverage and is pretty ugly to use.
In python I'd probably call the "Service Helper" layer described above as internal_api, but that seems to have a different meaning in Java, especially since I need the classes to be public to unit test them.
Any guidance is appreciated.
That the user who initiates the action must be an admin looks like an application-level access control concern. DDD doesn't have much of an opinion about how you should do that. For testability and separation of concerns purposes, it might be a better idea to have some kind of separate non-static class than a method in the same service or a static helper though.
Checking that the future owner is already an owner (if I understand correctly) might be a different animal. It could be an invariant in your domain. If so, the preferred way is to rely on an Aggregate to enforce that rule. However, it's not clear from your description whether Document is an aggregate and if it or another aggregate contains the data needed to tell if a user is owner.
Alternatively, you could verify the rule at the Application layer level but it means that your domain model could go inconsistent if the state change is triggered by something else than that Application layer.
As I learn more about DDD, my question doesn't seem to be all that DDD related and more just about general hierarchy of the code structure and interactions of the layers. We ended up going with a separate DocumentServiceHelpers class that could be mocked out. This contains methods like isOwner that we can mock to return true or false as needed to test our DocumentService handling more easily. Thanks to everyone for playing along.

Handling simple business process in MVC pattern?

I'm using spring-mvc and my controllers mostly contain too much logic. When 3 - 5 service beans constitutes the business process and they are called in one handler, then there is some validation included and it results in a few if-else conditions with positive or negative response.
One possible solution is having a facade that contains all references to service beans and common interface of their methods. This makes it simpler, it can also constitute exception boundary in the MVC pattern, but still, the business process has some logic and validation and it is still dealt with in the handler method.
Should I create something like this? :
BusinessProcess {
processOrder() {
serviceBeanA.call();
result = serviceBeanB.call();
validator.validate(result); // throw exception
serviceBeanC.call(result);
}
}
and use only BusinessProcess bean in my handlers ? Catching exceptions or return value would say what's wrong and what to include into the response. Otherwise content of processOrder method would be in handler.
Is it correct way ? How is this pattern called if so.
Most likely you should do as you suggest if I understood correctly. I don't think there's a name for this "pattern" nor needs to be. Since you seem uncertain, here's why I think you are thinking about the right thing.
Processing orders is an logical abstraction your handler is interested in. How the OrderProcessorBean (or BusinessProcessImpl) actually accomplishes this is an implementation detail and hidden from the handler/controller.
Not having such bean you may write a method processOrder in some controller and the controller has dependencies and references to service beans dealing with the details of processing orders. As you noticed this is not good design.
It also seems proper that the processing code lets exceptions fly out and is not bothered how they are handled by the caller. Perhaps a transaction is rolled back and perhaps some HTML containing error messages gets serviced to the end user, but the code (business logic) responsible for processing orders should not know that there are such things as Spring MVC or HTML.

Best practices in JSF: model, actions, getters, navigation, phaselisteners

I have got into a project for re factoring of JSF implementation. The existing code is not followied the proper JSF standards. To achieve that I am learning all the concepts in JSF ( I already have hands on experiance with JSF). To be specific I would like to ask questions what I have in mind.
In the MVC pattern, what is model component in the JSF? Is it the Managed Bean?
Is it good idea to write the business logic in the action methods? I have seen hundreds of lines written in action methods.
Do you think that we can write any logic in the getter methods?. How many times getter or setter called in the JSF lifecycle.
What is the conventional way of writing the faces-config.xml. I have read in one document that it says good practice to write the managed bean declaration and navigation case for that bean together. It will be more readable.
Writng the phase listener would affect the response time. For example, I am writing a logic to parse the request parameter in the PhaseListener and doing some logic. Is there any advice on this?
Please answer the above questions. If I am clear with the answer then I will come up with some more questions.
Note that even though you tagged [icefaces], this answer applies on JSF in general, not on IceFaces.
In the MVC pattern, what is model component in the JSF? Is it the Managed Bean?
That's correct. The View is the JSP/Facelets page. The Controller is the FacesServlet. For more detail about how it works "under the covers" see also this answer.
Is it good idea to write the business logic in the action methods? I have seen hundreds of lines written in action methods.
You can also delegate the call to a business service like an EJB. This way you can abstract the business details away. In "simple" applications it does usually not harm to leave that part away and do everything in the managed bean. However, once you comes to a point you'd like to change the business logic (e.g. for a different customer or for demo purposes, etc), then having a service would be more handy so that you don't need to change the managed beans but you just need to write another implementation class of a certain business interface.
Do you think that we can write any logic in the getter methods?. How many times getter or setter called in the JSF lifecycle.
If the business logic needs to be executed on every getter call, then do so (this is however very unlikely in real world, expect for insane logging or special lazy (re)loading cases). But if the business logic needs to be executed only once per action, event, request, session or application scope, it has definitely got to be executed elsewhere. See also this answer.
How many times a getter is called should be your least concern. The getter should do nothing else than returning the property in question. When called in output value, it can be once per request. When called in input value, it can be twice per request. When inside a datatable/repeat component, multiply the calls with amount of rows. When inside the rendered attribtue, multiply the calls with 6~8 times.
What is the conventional way of writing the faces-config.xml. I have read in one document that it says good practice to write the managed bean declaration and navigation case for that bean together. It will be more readable.
I myself use very seldom navigation cases, usually there are none in my faces-config.xml. I always post back to the same view (return null or void and then render/include the result conditionally. For page-to-page navigation I don't use POST requests (for which navigation cases are mandatory) simply because that's plain bad for UX (User eXperience; browser back button doesn't behave as it should and URL's in browser address bar are always one step behind because it are by default forwards, not redirects) and SEO (Search Engine Optimization; searchbots doesn't index POST requests). I just use outputlinks or even plain HTML <a> elements for page-to-page navigation.
Also, in JSF 2.0 there's technically no need for managed bean definitions and navigation cases in faces-config.xml. See also this answer.
Writng the phase listener would affect the response time. For example, I am writing a logic to parse the request parameter in the PhaseListener and doing some logic. Is there any advice on this?
This falls like as with servlet filters in the premature optimization category. Worrying about their performance makes usually no sense. This is per saldo usually only one or two lines of code extra. Really nothing to worry about. You would have much bigger problems when you copypaste that piece of code over all classes. If you really think that it costs performance, first profile it and then we can talk about it.
In the MVC pattern, what is model component in the JSF? Is it the Managed Bean?
I suggest this:
VIEW LAYER (consists of a mini MVC):
userForm.xhtml <-- view; the web page
UserController <-- controller; a managed bean
UserController.get/setUser <-- model; the model for the view
CONTROLLER LAYER:
UserService <-- controller; the controller that contains CRUD related business logic
UserDAO <-- persists objects to the database
User <-- the domain object that gets persisted
MODEL LAYER:
The database
Is it good idea to write the business logic in the action methods? I have seen hundreds of lines written in action methods.
In my example, put the business logic in the methods of the UserService. The action method of UserController doesn't do much more than call the method in the UserService, catch any exceptions and format the response for the next web page that is displayed.
Do you think that we can write any logic in the getter methods?. How many times getter or setter called in the JSF lifecycle.
Preferable for getter/setters to just do the getting/setting. No logic.
What is the conventional way of writing the faces-config.xml. I have read in one document that it says good practice to write the managed bean declaration and navigation case for that bean together. It will be more readable.
I declare all of my managed beans together. And declare all of my navigation rules together.
Writng the phase listener would affect the response time. For example, I am writing a logic to parse the request parameter in the PhaseListener and doing some logic. Is there any advice on this?
Not sure what you're doing exactly, but you shouldn't have to manually parse request parameters. JSF should inject the values of your form directly into the model of the view for you. Maybe I need more info about what you're trying to do.
Hope this helps.

Categories