2

I want to show in browser the body of a ResponseEntity returned by a Controller (using Spring):

return new ResponseEntity<>(l.getReachableDate(), HttpStatus.NOT_FOUND);

l.getReachableDate() returns a Date type, and I want to show it in a way like:

<header>
    <h1><span>Url is not reachable from</span> <!-- body --> </h1>
</header>

How can I get it shown?

Santiago Gil
  • 1,292
  • 7
  • 21
  • 52
  • 1) why do you not use the normal Spring MVC way to render a html file with an JSP template? – Ralph Jan 09 '16 at 10:13
  • 2) is is right that you html example is invalid? A HTML header is not allowed to contain html tags that are designed to be used in the body, like h1, span .... – Ralph Jan 09 '16 at 10:15
  • Hi @Ralph. 1) I think JSP is not allowed in Spring. 2) I don't know if it is invalid or it is not allowed, but it allows me. Maybe you are right and it is not a good way to do it, although it can be done. – Santiago Gil Jan 09 '16 at 10:29
  • 1) is wrong. The typical way to render a HTML page with spring is the MVC pattern (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html - have also a look at the image). So the spring controller build a model (map) and pass it to an rendering engine that puts some attributes of the model in an html template. Spring supports different rendering engines, the most common one is JSP, an other new rendering engine is Springs Thymeleaf. *(I am not taking about using JPS without MVC framework, this would be no good style)* – Ralph Jan 09 '16 at 10:39
  • @Ralph Okey, understood now. Yes, I am using Thymeleaf. I can get the dynamic data in html returning a ModelAndView. However, I didn't get a solution returning a ResponseEntity, that's the reason of my post. I am actually trying what prem kumar suggested. I throw an exception, and in the handler I return a ModelAndView. This way I am able to show the data. – Santiago Gil Jan 09 '16 at 10:52

2 Answers2

5

I still not understand why you want to do this, but this way it should work

@RequestMapping(value="/controller", method=GET)
public ResponseEntity<String> foo() {
    String content = 
           "<header>"
         + "<h1><span>Url is not reachable from</span>" +  l.getReachableDate() + "</h1>"
         + "</header>";
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentType(MediaType.TEXT_HTML);

    return new ResponseEntity<String>(content, responseHeaders, HttpStatus.NOT_FOUND);
}

after some comments....

Instead of redirecting the user to an resource not found page, it would been better to have an ResourceNotFoundRuntimeException (extends RuntimeException) and register an MVC exception handler (that is what prem kumar suggested, but wihtout the customized exception html text):

public class ResourceNotFoundRuntimeException extends RuntimeException{
...
}

The handler:

@ControllerAdvice
public class ExceptionHandlerController {

    @ExceptionHandler(ResourceNotFoundRuntimeException .class)
    public ResponseEntity<String> resourceNotFoundRuntimeExceptionHandling(){
        String content = 
               "<header>"
             + "<h1><span>Url is not reachable from</span>" +  l.getReachableDate() + "</h1>"
             + "</header>";
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setContentType(MediaType.TEXT_HTML);

        return new ResponseEntity<String>(content, responseHeaders, HttpStatus.NOT_FOUND);
    }
}
Community
  • 1
  • 1
Ralph
  • 118,862
  • 56
  • 287
  • 383
  • Something like this is what I wanted, but doesn't work. 1) I get incompatible type error in MediaType.TEXT_HTML (it expects MediaType but it is passed String, altought in the API that should work...). 2) I comment the content type line, but the desired data is not shown in browser [as you can see](https://i.gyazo.com/b0438729070623263e889f598b643e49.png). You can check my public repo [here](https://github.com/Santi-7/UrlShortener2015) – Santiago Gil Jan 09 '16 at 12:44
  • 1) you need to use: org.springframework.http.MediaType – Ralph Jan 09 '16 at 13:17
  • 2) do you have an 404 error page definied in your web,xml? – Ralph Jan 09 '16 at 13:18
  • 1) Solved, thanks 2) No, I redirect the user with `response.sendRedirect("notReachable.html");`. I just want to add the phrase "Url is not reachable from " in the image I have recently sended. Still doesn't show nothing. 3) I have same html in another pages, and they work. I think there is a confusion: I have both tags head and body, and inside body I have tag header. – Santiago Gil Jan 09 '16 at 13:37
  • Okey, if i don't redirect him, it is shown in browser you are right. But how can I get it shown in the page desired? – Santiago Gil Jan 09 '16 at 13:47
  • Thanks, it worked for me! But I only works in a `@RestController`, and I wanted it to work in a `@RepositoryRestController`. – GuiRitter Oct 28 '19 at 20:44
  • @GuiRitter - please raise a new question, something like "How to add an ExceptionHandler for Spring Data Rest Controllers?" – Ralph Oct 31 '19 at 12:34
  • @Ralph Thanks but it's not necessary. I'm not interested in `ExceptionHandler`s. I just wanted to return a simple HTML with a redirect to another URL. I managed to do that with [this](https://stackoverflow.com/a/17961336/1781376) – GuiRitter Oct 31 '19 at 19:47
1

If you want the entire body from server side using spring, then you can throw a custom ResourceNotFoundException and handle it using a spring exception handler.

Check the following links:

https://stackoverflow.com/a/21115267/5039001

The following link gives you different ways to do it.

https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

If you want different bodies for different urls, then you can have a property html body in ResourceNotFoundException and pass the body as a constructor argument and throw the exception. In exception handler, you can retrieve this body and build the http response message.

public class ResourceNotFoundException extends RuntimeException{
    private String htmlBody;
    public ResourceNotFoundException(String htmlBody){
        //super(...)
        this.htmlBody = htmlBody;
    }
}

You can now reuse this exception globally. Note that you need to setup a corresponding exception handler for this exception for which you can visit the above shared links.

Community
  • 1
  • 1
prem kumar
  • 5,641
  • 3
  • 24
  • 36