users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] Re: JSF MVC?

From: Leonardo Uribe <lu4242_at_gmail.com>
Date: Tue, 8 Apr 2014 18:22:44 +0200

Hi

I forgot to say something that becomes important before do any consideration
of this problem. As you see in every use case described, there is always an
alternative solution that solves the problem one way or another.

For some users who currently uses JSF at a daily basis, this problem is not
something important, because there is a workaround and this usually suppose
a small part of the whole application, so you don't really spent a lot of
time solving it. It is not really hard to write a couple of servlets that
can do the job in these cases.

But for some other users that are not into JSF, this is important. The reason
is JSF Template engine (Facelets) solves a lot of problems for them. These
guys usually are making applications with another architectural paradigm,
different to the one proposed initially by JSF.

It is really important to impose a way to do things, like for example define
a specific architectural model? or what JSF should do is like JSF 2.2
section 1.1 says "... solving practical problems of the web ...". At the
end, JSF MVC could be a product that could be consumed by different users
in different ways. That sounds good.

regards,

Leonardo Uribe


2014-04-07 15:48 GMT+02:00 Leonardo Uribe <lu4242_at_gmail.com>:
> Hi
>
> I'm still thinking about this problem, because it looks like it has the utmost
> relevance for users in general. So, I would like to make a contribution in
> this part, giving some ideas and specifying some possible use cases where we
> could find some inspiration. It is clear there is some interest, but to put it
> into the spec it is necessary to be more specific about the requeriments,
> and more concrete about the proposals.
>
> I would like to write an extension for this and contribute it into MyFaces
> project, but since there is interest on the EG, I would to propose the ideas
> here first, because at the end we don't want to replicate work in multiple
> places, just do it once and do it right. I believe more in "quantity" of ideas
> than in "quality", so the idea is make a depuration of the initiatives, based
> of the perception and experience of the people involved.
>
> From start, I would like to focus on this question provided by Arjam Tijms:
>
> AT>> Is it because JSF is not popular enough, or are there specific use cases
> AT>> JSF can't address?
>
> I think JSF can handle most of the cases, but it is clear in some cases it
> just doesn't help much. JSF Component libraries usually take advantage of the
> extensibility of JSF and can fill the gaps, but for a regular user it can
> become a complex task. So, we need to find ways to make these tasks easier.
>
> Let's take a look at some cases:
>
> CASE 1: Autocomplete component
>
> In JSF you usually don't want to get your hands dirty with this stuff, instead
> you use a JSF library with a custom autocomplete component that do this
> integration behind curtains. But let's think for a while that in our particular
> case that solution doesn't fit, and we want to do it ourselves by hand.
>
> With jQuery, on the client side you can add a script like this:
>
> $('#input').autocomplete({
> source: "/example/location/example.json"
> });
>
> or this
>
> $("#input").autocomplete({
> source: function (request, response) {
> $.post("/AjaxPostURL", request, response);
> }
> });
>
> The first problem you found with JSF is that you cannot "easily" customize the
> response. In this case we need to create an endpoint that returns JSON data.
> It can be through a GET or a POST. What can the user do right now in this case
> with JSF? There are several options:
>
> 1. If you are in a Java EE container, you could use JAX-RS to create the
> endpoint and access the CDI beans.
> 2. If you are not in a JEE container, you can create a custom
> PhaseListener, add the controller logic manually and call
> facesContext.responseComplete().
> 3. If you are not in a JEE container, you can provide a custom servlet,
> try to create a FacesContext instance and call the code from there, see:
>
> http://myfaces.apache.org/wiki/core/user-guide/jsf-and-myfaces-howtos/backend/access-facescontext-from-servlet.html
>
> 4. You can write a JSF page and using f:viewParam and f:viewAction create
> the necessary JSON response. This involves generate JSON from facelets.
> This only works for the GET case. In this case JSF is used as a
> template engine. See some strategies here:
>
> http://stackoverflow.com/questions/8358006/jsf-json-output-plain-text-in-servlet
>
> All previous cases can present the following problems:
>
> 1. Some beans are only accesible if the context is correctly set. Beans
> created using FlowScope or ConversationScope or anything smaller than
> Session scope cannot be accessed from the endpoint.
> 2. An endpoint like that can be affected by different security problems,
> that are avoided by JSF, because there is a ViewState token and in JSF
> 2.2 a client window id which cannot be guessed easily. So, in some
> cases, you would want to send these two parameters and update them,
> just like in a ajax request.
> 3. It could be some parameters necessary for the autocomplete to work.
> For example the autocomplete works in one way if the selection box is
> selected and in other way if it is not. So, you could want to do a
> POST request that execute the lifecycle just like f:ajax, but on the
> render response phase, the control is passed to something else like
> another jsf template, or a managed bean method or something like that.
>
> Solutions? The GET case can be fixed using facelets to generate the JSON
> response.
>
> I could imagine something like this:
>
> $("#input").autocomplete({
> source: function (request, response) {
> jsf.rest.doPost( $('#input').attr('id'),
> event,
> { execute : '_at_form',
> renderAction : 'action-to-execute-and-render'}, ... );
> }
> });
>
> It looks similar to jsf.ajax.request(source, event, options), but it is a
> JSF POST request, with javax.faces.ViewState and javax.faces.ClientWindow but
> it has a difference: it doesn't trigger an ajax update (it could be, but the
> main objective is not that). It is a "partial" request, but it is not an
> "partial/ajax" request. I mean, the objective is return somehow the data
> in the response in some specified format so the user can take it using
> javascript or jQuery and use it.
>
> Please note the lifecycle is executed as usual, but the component does not
> render the response, there is some kind of "renderAction" associated to
> the component and in that sense to the view and by that way it could be
> associated to the managed bean. It is a POST request to the view, but it is
> not a POST that renders view markup. Instead it is a POST that comunicate
> with the server and bring back some information without alter the current
> server side view state. It could change a value in a ViewScope bean for
> example, or even alter the view state, but the thing is we should make
> it in a way that the user does not see the underlying update. From the
> user point of view it is a POST that return JSON, but maybe internally
> it could be a POST that use a mix between XML and JSON to deliver the
> response.
>
> Is this still JSF? Yes, of course it is. JSF takes care of the templating,
> the HTML markup, maintain the context, and javascript provides the logic in
> the client.
>
> The difference this is JSF being friendly with Javascript!. There are tons
> of javascript components with the same integration problem. If we can fix
> this somehow, it would be a big step forward.
>
> CASE 2: Captcha component
>
> Suppose you are creating a custom captcha component. The code could look
> something like this:
>
> <input jsf:id="captcha_input" value="#{bean.value}"/>
> <img jsf:id="captcha_img" url="..."/>
>
> There is an input, but you need to generate an image on the fly. How? one way
> is create a ResourceHandler wrapper implementation and activate it using an
> specified library name. Then, inside handleResourceRequest(...) you provide the
> necessary logic to take the secret value stored in the server and generate
> the image based on that value. And quickly you have found a problem: you want
> to store the secret value in the server. The component tree does not work
> because that info can travel to the client if state saving is set to client,
> and you want to secure the captcha storing the value in the server.
>
> But the request that gets the image from the client does not have the same
> context as the page request. It has the same session, because all requests
> in a browser share the same session, but it doesn't have any associated
> client window id. It raises some challenges:
>
> 1. It is not possible to send a POST, because we require an URL, but we don't
> want to send the ViewState in the GET, because that let it in the history.
> 2. Facelets doesn't work to generate images.
> 3. How to get the secret? using a known key that store the secret in a scope
> inside server. Which scope? session scope? window scope? flash scope?
>
> In this case, it could be enough to send a request that restore everything
> until window scope but render something arbitrary using the information
> available as query parameters. How it looks something like:
>
> <img jsf:id="captcha_img"
> url="/javax.faces.endpoint/captcha.jsf?jfwid=#{externalContext.clientWindow.id}&ln=com.my.captcha&k=#{cc.attrs.key}"/>
>
> So, the component by default already sets up an endpoint that receive the
> request, it has as parameters:
>
> * The client window url query param, in this case "jfwid"
> * The library name, in "ln" query param
> * The resource name, in this case captcha.jsf
> * Additional parameters for the request
>
> The idea could be simplify the url generation with something like:
>
> <img jsf:id="captcha_img"
> url="#{func:endpoint('com.my.captcha:captcha',
> 'k=#{cc.attrs.key}')}"/>
>
> or do the logic through a some few java lines in the base component
> class, passing the parameters as a map.
>
> <img jsf:id="captcha_img" url="#{cc.imgUrl}"/>
>
> The component should look something like this:
>
> @Path(libraryName="com.my.captcha", resourceName="captcha")
> @FacesComponent(namespace = "http://my.namespace.com/components",
> createTag = true, tagName = "captcha",
> value = "com.myapp.CaptchaComponent")
> public class CaptchaComponent extends UIComponentBase
> {
>
> @Mapping(...)
> public static void handleCaptchaImage(FacesContext context)
> {
>
> }
> }
>
> I hope you already get the idea. It could look like the ResourceHandler
> or the syntax can be fixed to use something closer as an action source
> framework looks. Let's make a summary
>
> * JSF scan the component library at startup time and find all endpoints
> exposed by components.
> * JSF provides an API for syntethize an URL for a component that should
> map to an endpoint.
> * JSF provides a front controller algorithm in the same way as an action
> source framework, so the url can be processed.
> * The endpoint has the same client window context as the page request
> that renders the URL.
>
> This is getting good, because this also works for the case 1. This is not
> create an action source framework inside JSF, it is something even better,
> a mixed component/action approach for JSF that fit very well between each
> other.
>
> We could extend even more the syntax. Suppose a function that points to
> the mapping in this way:
>
> <img jsf:id="captcha_img" url="#{func:endpoint(mybean.handleCaptchaImage)}"/>
>
> The idea could be that the function scan the final method class
> automatically and derive the mapping automatically. In this case it is clear
> we need to provide the key, so it doesn't really work, but in other cases
> it could work.
>
> CASE 3: Excel/PDF/Text/CSV export
>
> In this use case, the user needs to generate some information in excel or PDF
> or CSV or whatever, usually to export some data. The known solutions to this
> problem are:
>
> 1. Use a JSF component that do the necessary work for you.
> 2. Write a command button in this way ( taken from
> http://balusc.blogspot.co.at/2006/05/pdf-handling.html )
>
> public void download() throws IOException {
>
> // Prepare.
> FacesContext facesContext = FacesContext.getCurrentInstance();
> ExternalContext externalContext = facesContext.getExternalContext();
> HttpServletResponse response = (HttpServletResponse)
> externalContext.getResponse();
>
> // ... Output the file in the response.
>
> // Inform JSF that it doesn't need to handle response.
> // This is very important, otherwise you will get the
> following exception in the logs:
> // java.lang.IllegalStateException: Cannot forward after
> response has been committed.
> facesContext.responseComplete();
> }
>
> 3. Create a servlet that handle the request. See
> http://balusc.blogspot.co.at/2007/07/fileservlet.html for an example.
>
> What's the problem here? The context. Suppose solution 2 is not good for you,
> because you are using Post-Redirect-GET pattern, or for example you want to
> create a link to download the generated file, but on the way preserve the
> current context, so the information can be generated. We have the same base
> scenario as the captcha component, which is generate an url that has the same
> context as the current window. The argument here is the servlet has another
> context different that the one defined by JSF. How can you handle this in
> a Portlet? again the problem is the context, and the ideal solution is provide
> something in JSF that handle these kind of request in a standarized way.
>
> CASE 4: REST
>
> This case is similar to the previous case. What raises my attention here
> is that there is evidence, that other component oriented frameworks
> like Wicket and Tapestry have already considered the possibility of
> define REST services, but that does not means everything is done using
> that approach.
>
> In JSF, people has been using for some time PrettyFaces to generate RESTful
> URL links. This library has compatibility with JSF 1.1, 1.2 and 2.0, and
> seems to be very popular. Also, some users also use the combination between
> JSF and other web frameworks like Spring MVC or JAX-RS, specifically to
> deal with those cases where it is required to define a REST service. With
> Spring MVC you have Spring Beans and with JAX-RS you can integrate it with
> CDI, so in this case the evidence suggest people use JSF to do what JSF
> do the best (component oriented approach, validation, state management,
> server side templating, ...) and use the MVC stuff for the REST services.
>
> Why some users seems to like the idea of define REST service into JSF? by
> simplicity, because they have already done 90% of the job just with JSF,
> but for the remaining 10% or 5% or 1% they require to define a REST service
> or something like that, usually to expose it or consume it using javascript
> from the client side, usually embedded in a page written using JSF. In
> other words, to avoid the round trip to JAX-RS and the way back to JSF.
>
> CASE 5: Websockets
>
> There are few things to say in this part, but that this is an example where
> an "application" scope endpoint can be important. In this case, there is
> a communication between the client written in javascript and the server
> in java. In this case a declaration of such endpoints works just the same
> and the important part here is the integration with CDI. If you have an
> application in JSF, you want to access to the same beans. But you could
> also use JSF inside a websocket to generate some content. Something like
> this:
>
> session.getBasicRemote().sendText(
> JSF.renderView("/META-INF/responses/myView.xhtml", ...));
>
> In other words, use JSF template engine to generate all kinds of responses,
> without any restriction. Maybe it is a too simplistic example, but in
> fact JSF could provide that flexibility with just some fixes and a good
> API. That's something really attractive, because we are unleashing the
> potential of JSF to do even more things.
>
> CONCLUSIONS:
>
> AT>> Is it because JSF is not popular enough, or are there specific use cases
> AT>> JSF can't address?
>
> In my personal opinion, there are some cases that JSF is not solving right
> now, but JSF has the potential to solve them even better than anything you
> can find out there, in a mixed component/action way.
>
> There are different points of view in all this discussion:
>
> 1. Some people want to see JAX-RS on top and JSF as a template engine.
> 2. Some people want to see JSF on top with built-in action oriented features,
> but keeping its own component-oriented approach.
> 3. Some people want to see JSF with built-in REST features, replicating
> the same features as in JAX-RS, because after all that code doesn't have
> anything to do with JSF.
>
> My priority list is do 2., then 3. and finally 1. . It can be done, if we push
> hard enough. The idea is so tempting that it sounds like a nice extension for
> JSF 2. But even better if we can push this for the spec.
>
> It is up to the EG to decide what to do. On the mean time I'll keep trying to
> find new ideas.
>
> regards,
>
> Leonardo Uribe
>
> 2014-04-05 23:21 GMT+02:00 Leonardo Uribe <lu4242_at_gmail.com>:
>> Hi
>>
>> 2014-04-05 17:52 GMT+02:00 Frank Caputo <frank_at_frankcaputo.de>:
>>> Hi all,
>>>
>>> I've been thinking much about this MVC thing. From my point of view, we
>>> should not focus on JSF only, instead take a look at some more specs like
>>> JAX-RS, Servlet/JSP and JSF.
>>>
>>
>> +1
>>
>>> I think many of the samples given by Adrian can be implemented in Java EE by
>>> simply forwarding from JAX-RS to the Faces Servlet.
>>>
>>> Use a JAX-RS resource. Define the model with @Model (which is actually
>>> @Named @RequestScoped), inject it in your JAX-RS bean and simply use it from
>>> JSF.
>>>
>>> Then you can do something like this (the code isn't tested):
>>>
>>> @Path("/exemple/clients")
>>> public class ClientResource {
>>>
>>> @Inject
>>> private ClientModel model; // ClientModel is annotated with @Model
>>>
>>> @Inject
>>> private ClientManager clientManager;
>>>
>>> @GET
>>> @Path("{id}")
>>> public void show(@Context HttpServletRequest request, @Context
>>> HttpServletResponse response, @PathParam("id") String id) throws Exception {
>>> Client lClient = clientManager.findById(id);
>>> model.setClient(lClient);
>>> model.setItemId(id);
>>>
>>> request.getRequestDispatcher("/exemple/clients/show.faces").forward(request,
>>> response);
>>> }
>>>
>>> }
>>>
>>
>> In JSF there is ExternalContext as an abstraction of the underlying environment.
>> I would prefer use JSF existing stuff in that part, and refer to the parameters
>> as something not coupled with servlet spec. The only flaw I can see is using
>> ExternalContext there is no way to know when the request is a GET, a POST
>> and so on, which is important at the time to define the endpoint.
>>
>>> We should simply collect SpringMVC examples and port them to Java EE. I'm
>>> willing to do so, but I don't have experience with SpringMVC. So examples
>>> should be provided by others.
>>>
>>
>> I ported some time ago a simple booking app to SpringMVC in the performance
>> comparison done some time ago. See:
>>
>> https://github.com/lu4242/performance-comparison-java-web-frameworks
>>
>> There you can find the same app written in different web frameworks, including
>> JSF 2 of course, but it is quite helpful. It could be interesting to check how
>> some typical use cases are solved by different frameworks, as a way to get
>> some inspiration.
>>
>> I consider JSF approach is all about define an abstraction so you can build
>> complex applications and reuse components easily. One thing that JSF solve
>> pretty well is the id problem. In other words, generate ids for the components
>> available in the page. In an action source framework there is not such concept
>> but that makes things difficult to reuse, because each time you need to use
>> something in other place, you usually need to rename the ids.
>>
>> Now, it could be useful to have a "action source framework" component. That
>> means, an special component that work in a way that everything inside it works
>> just like any action source framework, but everything outside the box still work
>> under JSF rules.
>>
>> In that sense, allow a syntax to define "endpoints" in managed beans is a part
>> of the problem we know that it could be useful. But there are other parts where
>> people don't really want to solve everything in the same way as an action
>> source framework is solving, because in those parts JSF just do a better job.
>>
>> Does somebody out there already provided something that we can take as a
>> source of inspiration? Just look for the competition.
>>
>> - Type on google "wicket rest", and you will find a couple of articles that
>> aims to do something similar.
>> - Type on google "tapestry rest", and you will find something like tynamo.
>>
>> So, other people has already thought the same as we are trying to do and
>> have been doing (JSF 2.2 viewAction and JSF 2.0 viewParam), there are
>> some cases where an action oriented approach with a component oriented
>> framework can coexist. In that sense, the ability to define REST services
>> inside CDI managed beans through Faces Servlet seems to be important.
>> For what? It is not hard to find cases. For example, to expose information
>> to some other app or component or service that consume it as a REST
>> service. If you have a JSF webapp nothing can be simpler as define the
>> method right on the managed bean.
>>
>>> Maybe we can add them to https://github.com/javaee-samples/javaee7-samples
>>> or create a dedicated github-repo for it.
>>>
>>
>> +1 for use github.
>>
>> I have a proposal to discuss different use cases and ideas I have on my sleeve,
>> that still need some review from my side, but I hope to send it to the
>> list in some
>> few days.
>>
>> regards,
>>
>> Leonardo
>>
>>> Ciao Frank
>>>
>>> Am 01.03.2014 um 21:57 schrieb Adrian Gonzalez <adr_gonzalez_at_yahoo.fr>:
>>>
>>> [1] An action-based controller with Spring MVC
>>> @Controller
>>> @RequestMapping(value = "/exemple/clients")
>>> public class ClientController {
>>> @Inject
>>> private ClientManager clientManager;
>>>
>>> @RequestMapping(value = "/{id}", method = RequestMethod.GET)
>>> public String show(@PathVariable Long id, Model uiModel) {
>>> Client lClient = clientManager.findById(id);
>>> uiModel.addAttribute(lClient);
>>> uiModel.addAttribute("itemId", id);
>>> return "exemple/client/show";
>>> }
>>>
>>> @RequestMapping(method = RequestMethod.POST)
>>> public String create(@Valid Client client, BindingResult bindingResult,
>>> Model uiModel) {
>>> String inputView = "exemple/client/edit";
>>> if (bindingResult.hasErrors()) {
>>> return inputView;
>>> }
>>> client.setDateContact(new Date());
>>> try {
>>> clientManager.create(client);
>>> } catch (SomeBusinessException e) {
>>> bindingResult.reject("error.global", e.getMessage());
>>> return inputView;
>>> }
>>> uiModel.asMap().clear();
>>> return "redirect:/exemple/clients/" + client.getId();
>>> }
>>>
>>> @RequestMapping(params = "form", method = RequestMethod.GET)
>>> public String createForm(Model uiModel, SitePreference sitePreference) {
>>> uiModel.addAttribute(newClient());
>>> return "exemple/client/edit";
>>> }
>>> @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
>>> public String delete(@PathVariable Long id, Model uiModel, SitePreference
>>> sitePreference) {
>>> Client client = clientManager.findById(id);
>>> clientManager.delete(client);
>>> uiModel.asMap().clear();
>>> return "redirect:/exemple/clients" + (sitePreference.isMobile() ? "-mobile"
>>> : "");
>>> }
>>> @RequestMapping(method = RequestMethod.PUT)
>>> public String update( @Valid Client client, BindingResult
>>> bindingResult,Model uiModel) {
>>> String inputView = "exemple/client/edit";
>>> if (bindingResult.hasErrors()) {
>>> return inputView;
>>> }
>>> try {
>>> clientManager.update(client);
>>> } catch (MatriculeExistantException e) {
>>> bindingResult.reject("error.global", e.getMessage());
>>> return inputView;
>>> }
>>> uiModel.asMap().clear();
>>> return "redirect:/exemple/clients/" + client.getId();
>>> }
>>>
>>> @RequestMapping(value = "/{id}", params = "form", method =
>>> RequestMethod.GET)
>>> public String updateForm(@PathVariable Long id, Model uiModel) {
>>> show(id, uiModel);
>>> return "exemple/client/edit";
>>> }
>>>
>>> @RequestMapping(method = RequestMethod.GET)
>>> public String list(@Valid ClientCriteriaForm clientCriteriaForm,
>>> BindingResult aBindingResult,
>>> Model uiModel) {
>>> if (aBindingResult.hasErrors()) {
>>> return "exemple/client/list";
>>> }
>>> ...call clientManager...
>>> uiModel.addAttribute("clients", clients);
>>> return "exemple/client/list";
>>> }
>>>
>>> @RequestMapping(params = "list", method = RequestMethod.GET)
>>> public String listForm(ClientCriteriaForm clientCriteriaForm, Model uiModel)
>>> {
>>> List<Client> clients = new ArrayList<Client>();
>>> uiModel.addAttribute("clients", clients);
>>> return "exemple/client/list";
>>> }
>>> @RequestMapping(params="cancel")
>>> public String cancel() {
>>> return "redirect:/exemple/clients";
>>> }
>>> }
>>>
>>> [2] A REST backend controller with Spring MVC
>>> @Controller
>>> @RequestMapping(value = "/exemple/rest/clients")
>>> public class RestClientController {
>>>
>>> @Inject
>>> private ClientManager clientManager;
>>>
>>>
>>> @RequestMapping(method = RequestMethod.GET)
>>> @ResponseBody
>>> public Map<String, Object> list(@Valid ClientCriteriaForm
>>> clientCriteriaForm) {
>>> List<Client> clients = clientManager.findByName(
>>> clientCriteriaForm.getNom(), clientCriteriaForm.getPage()
>>> * clientCriteriaForm.getSize(),
>>> clientCriteriaForm.getSize() + 1);
>>> Map<String, Object> lResults = new HashMap<String, Object>();
>>> if (clients.size() > clientCriteriaForm.getSize()) {
>>> lResults.put("hasNextPage", true);
>>> lResults.put("page", clientCriteriaForm.getPage());
>>> clients.Remove(clientCriteriaForm.getSize().intValue());
>>> }
>>> lResults.put("clients", clients);
>>> return lResults;
>>> }
>>>
>>> @RequestMapping(value = "/{id}", method = RequestMethod.GET,
>>> produces="application/json")
>>> @ResponseBody
>>> public Client show(@PathVariable Long id) {
>>> return clientManager.findById(id);
>>> }
>>> @RequestMapping( method = RequestMethod.POST, produces="application/json")
>>> @ResponseBody
>>> public Client create(@RequestBody @Valid Client client) throws
>>> SomeBusinessException {
>>> return clientManager.create(client);
>>> }
>>> @RequestMapping(value = "/{id}", method = RequestMethod.DELETE,
>>> produces="application/json")
>>> @ResponseStatus(HttpStatus.NO_CONTENT)
>>> public void delete(@PathVariable Long id) {
>>> Client client = clientManager.findById(id);
>>> clientManager.delete(client);
>>> }
>>>
>>> @RequestMapping(method = RequestMethod.PUT, produces="application/json")
>>> @ResponseBody
>>> public Client update(@RequestBody @Valid Client client) throws
>>> SomeBusinessException {
>>> return clientManager.update(client);
>>> }
>>> @ExceptionHandler(RequestBodyNotValidException.class)
>>> @ResponseBody
>>> public Map<String,Object> handleException(RequestBodyNotValidException
>>> exception, HttpServletResponse response) throws IOException {
>>> return RestUtils.convertAndSetStatus(exception, response);
>>> }
>>> @ExceptionHandler(Exception.class)
>>> @ResponseBody
>>> public Map<String,Object> handleException(Exception exception,
>>> HttpServletResponse response) throws IOException {
>>> return RestUtils.convertAndSetStatus(aException, aResponse);
>>> }
>>> }
>>>
>>>
>>>