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.
Related
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.
After reading a lot about the abusive use of exceptions in Java and how you should let an exception bubble up through the different layers of an application, I've come to a point where I don't know what I am supposed to do with the potential errors my application can have.
Basically, I have a webservice which uses the DAO pattern to access data in my database. All of the database actions can throw a SQLException.
As of today, I'm using a try catch to catch the SQLException and then thow a specific defined exception called ExceptionDAO that will be handle by the webservice to return a correct message to the users (a mobile application) of my webservice.
After reading a lot about how exception should be exceptional and should not be used in control flow, I've come up with a mixed understanding of what I should do to handle any errors:
Use return codes for anything that is likely to happen (e.g. username already exists) and therefore, to comply with the DAO pattern, pass my business objects as parameters instead. I could also use a specific pair which would return the code + the business object instead. The webservice would then use the return code to display a specific message.
Use checked exceptions for anything that I can't predict will happen and let them bubble up to the webservice to handle and return a message to the users. (e.g. SQLException that I can't predict : connection aborted)
Let unchecked exceptions bubble up aswell and display a sort of 404 error in this case.
I also had a look at the null pattern but I don't think it suits this particular situation really well.
I'm also concerned to not give too much information to the users, but rather useful and straight to the point information. Indeed, the messages returned by the webservice will be used by a mobile application to then display a message to the end-user.
I hope that I was clear enough about the problem I'm having, and I'm looking forward to your answers !
Return codes are suitable for C, which lacks exception handling among its features. For Java, please use exceptions, either checked or runtime, that's a matter of taste.
Personally, I hate checked exceptions, because they pollute my method signatures with information of border cases that might never occur. But maybe you want to be strict with the contract of your classes, even for such exceptional cases. If that's your case, then use checked exceptions. Otherwise, let your method signatures in peace and throw a runtime exception whenever you detect an exceptional case (such as an entity not found, entity already exists, etc).
Please note that ExceptionDAO is not a happy name. It appears to be a dao that handles exceptions. Maybe something like PersistenceException would be better.
Apart from that naming detail, I think your approach is on the right way, though not ideal. Ideally, you wouldn't need to do a try/catch for SQLExceptions inside every method that calls methods from your DAOs (or inside every method of your DAOs). Instead, a persistence exception translation mechanism would be much better. Spring, for instance, comes with one by default. Spring accomplishes this by proxying every DAO, and by letting its proxies perform a try/catch around every method invocation. Then, specific SQLExceptions with specific SQL error codes are translated to Spring's own DataAccessException hierarchy. So, in the upper layers, you would end up with a specific DataAccessException, but you wouldn't need to do a try/catch inside every method.
If you are already using Spring, then you have nothing to do, but if you aren't using it and have either many DAOs or many methods that might throw SQLExceptions, and all your DAOs implement an interface, then it might be worth the effort to implement a proxy that intercepts all the methods of your DAOs and performs a try/catch around them. Then, in this interceptor's catch block, you'd throw your ExceptionDAO (please rename it!) with a message that would depend on the original SQLException (and maybe on its SQL error code, too).
This approach has the advantage that you could handle all persistence exceptions in a single point of your program.
This very same concept could be applied to your web layer as well. Instead of letting every method of your endpoints handle your ExceptionDAO (don't forget to rename it!), you could create a proxy that intercepts every method call and perform a try/catch around it. You could then extract the message from the exception and send it in the response (or whatever you find suitable to do with it). Again, this is all based in Spring, this time, in Spring MVC Exception Handling mechanism. Here you could also handle unexpected exceptions, i.e. RuntimeExceptions and provide an appropriate message to your users.
The advantage, again, would be that you could handle all the exceptions that reached your web layer in a single point of your program.
Please see Proxy javadocs and this tutorial for further reference on Java's proxies.
I think you are missing an important option, which is the observer pattern.
In your DAO you can have this:
public interface OnExceptionInteractionListener {
public void onExceptionInteraction(String exceptionMessage);
}
I would have the DAO be something like:
public SomeDAO(OnExceptionInteractionListener listener, ...) {
}
and I would instantiate the DAO as
SomeDAO s = new SomeDAO(new OnExceptionInteractionListener() {
public void onExceptionInteraction(String exceptionMessage) {
}
}, ...);
So, if there is an exception caught then call the listener in the DAO and the next level up will handle it.
This is better performance than throwing exceptions, and better than return codes.
For more on this you can look at this answer, for other examples: https://stackoverflow.com/a/18585099/67566
I haven't tried it but I expect that lambda expressions would be useful for this also, if you are using Java8.
Return codes are very old-school. Ideally, you should do your insert in some sort of transaction that checks:
Lock username inserts
Is this username available?
3a. If so, insert and unlock
3b. If not, unlock and inform user
If that's not possible, then a return object wrapping the result if it was created successfully and response Enum with potential outcomes.
I have the following method in my service layer.
public void delete(int candidateId) {
candidateRepository.delete(candidateId);
}
Pretty basic, now this method is used by the web layer which RESTful architecure is applied.
The URL that will trigger this method is:
DELETE /candidates/{id}
How should I deal with wrong ids given by the clients that use the REST API in the service layer? I know the HTTP response would be 4xx but how should I communicate that the id is invalid between the service and web layer?
Should I use a unchecked exception since this is a condition that my application is unable to recover from? The fault barrier (Spring exception handler) will deal with it.
Or should this be a checked exception since it is possible that clients give wrong ids?
I am using the latest Spring technology if that matter
If it is possible that clients give wrong ids, then they will give wrong ids. And this is a condition that your application should be able to recover from.
I would return a checked exception for this. But introducing a checked exceptions can sometimes mean changes throughout different layers of the application, because, for example, the signatures of many methods would need to be changed to add the "throws" clause (breaking OCP). In case that gets overcomplicated some people (like in Robert C. Martin's "Clean Code") recommend using unchecked exceptions. I would say it's up to you what to return as long as the exception has a meaningful description.
Firstly, you need to decide how your REST API will handle exceptions. There are multiple, equally valid solutions to this.
When designing an API, you pretty much have to assume that whatever can go wrong, will go wrong. Client applications will pass incorrect parameters, use incorrect formats, etc.; your application should expect this, and handle it gracefully.
Using exceptions to communicate business logic is not particularly readable, and may have performance implications. It really doesn't scale beyond very simple cases - imagine that the business logic for "delete" might need to include failures for "record not found", "record has dependent relationships", "record protected", "record archived" etc.
Instead, I would design the application to pass explicit status information back and forth, and translate this into whatever RESTful error handling you use.
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.
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(...);
}