3

I looked for similar questions but didn't understand some things. My code also seems to work, but instead of jpg images it displays some icons. Would be great if you will help to figure it out.

Fisrst of all, the controller:

@Controller
public class MainController {

@Autowired
private MasterpieceService masterpieceService;

@RequestMapping(value={ "/", "/home" }, method = RequestMethod.GET)
public ModelAndView firstPage(){
    ModelAndView model = new ModelAndView();
    model.addObject("masterpiece", new Masterpiece());
    model.addObject("masterpieceList", masterpieceService.getMasterpieces());
    model.setViewName("home");
    return model;
}

(...other methods...)


    @RequestMapping(value = {"/uploadMasterpiece"}, method = RequestMethod.POST)
public ModelAndView uploadMasterpiece(@RequestParam("name") String name,
                                      @RequestParam("file") MultipartFile file,
                                      @RequestParam("comment") String comment) {
    ModelAndView model = new ModelAndView();

    if(file.isEmpty()){
        // oh no.
        model.setViewName("home");
    }else {
        Masterpiece masterpiece = new Masterpiece();
        try {
            masterpiece.setName(name);
            masterpiece.setImage(file.getBytes());
            masterpiece.setComment(comment);
            masterpieceService.addMasterpiece(masterpiece);

            model.setViewName("admin");
        }catch (Exception e){
            e.printStackTrace();
            model.setViewName("home");
        }
    }
    return model;
}}

and my JSP:

<c:if test="${!empty masterpieceList}">
<table>

    <c:forEach items="${masterpieceList}" var="masterpiece">
        <tr>
            <td>${masterpiece.name},</td>
            <td><img src="${pageContext.request.contextPath}/masterpiece/${masterpiece.image}" /> </td>
            <td>${masterpiece.comment} </td>
        </tr>
    </c:forEach>
</table>

In the end it should be like an artist gallery representing a table of images on the first page. Right now I don't have any css and didnt search how to make a good table out of the output, but the question is about images. It looks like:

enter image description here

, with icons instead of images, and I am wondering, why...

SOLUTION

After comments and answers, I eventually find out a solution. Previously I tried to pass images straight, not as an url values, which appears a bad practice. Here is a code in the controller for my case:

@RequestMapping(value = "/something/getImg{masterpieceId}", method = RequestMethod.GET,
        produces = MediaType.IMAGE_JPEG_VALUE)
public ResponseEntity<byte[]> ListImage(@PathVariable long masterpieceId) throws IOException{
    Masterpiece m = masterpieceService.getMasterpieceById(masterpieceId);
    byte [] image = m.getImage();
    final HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.IMAGE_JPEG);
    return new ResponseEntity<byte[]>(image, headers, HttpStatus.CREATED);
}

And my updated form:

 <c:if test="${!empty masterpieceList}">
<table>

    <c:forEach items="${masterpieceList}" var="masterpiece">
        <tr>
            <td>${masterpiece.name},</td>
            <td><img src="/something/getImg${masterpiece.masterpieceId}" /> </td>
            <td>${masterpiece.comment} </td>
        </tr>
    </c:forEach>
</table>

St.running
  • 175
  • 1
  • 3
  • 14
  • When the HTML (JSP) does get rendered on the browser, what does "${masterpiece.image}" resolve to? – Mecon May 26 '15 at 14:36
  • My Masterpiece entity class have Strings name and comment and a byte array (byte []) called image. So, masterpiece.image = byte [] image, I suppose – St.running May 26 '15 at 14:44
  • can you look at the HTML source (i.e. "view source") of your webpage, and tell us what the HTML for the tag looks like? – Mecon May 26 '15 at 14:47
  • inspect-element option in browser gave me html for the picture as something like this: < img src ="/masterpiece/[B@53d2ffbo]"> ..strange, yes. – St.running May 26 '15 at 18:09
  • that's the "toString()" output for your byte[] array. – Mecon May 26 '15 at 18:10
  • tried another options, but still in vain (see updates) – St.running May 28 '15 at 14:23
  • 1
    Images can't be (shouldn't be) inserted like data in HTML. An Image should be loaded by a URL. 1. Make HTML be like this: img src="/something/getImg?id=123" 2. Create a controller that accepts URL "something/getImg". 3. In the Controller, return the Image by using Servlet's response.Outputstream – Mecon May 28 '15 at 14:30
  • Looks like there is a "Spring MVC way" to return images as well. http://stackoverflow.com/questions/5690228/spring-mvc-how-to-return-image-in-responsebody – Mecon May 28 '15 at 14:33
  • And if a need to return a list of images both with comments to each of them, I should make a form with mapping url like "something/getImg{id}"? And is it the best way to process a list? – St.running May 28 '15 at 14:45
  • For each image you want to display, create an IMG html element. Each IMG's "src" attribute will point a specific URL for that image: ..getImage?id=111 , getImage?id=112, etc. The controller method will look for request parameter "id", and return the Image for that id. – Mecon May 28 '15 at 15:45
  • damn! there is a silly exception "Failed to convert value of type 'java.lang.String' to required type 'int';" : because I got @RequestMapping(value = "/something/getImg{masterpieceId}" ... and a PathVariable masterpieceId as an int. Appears, that all the value is taken as a string. could you please advice, how to do it properly? I think\hope its the last error – St.running May 28 '15 at 19:50
  • What does your HTML looks like for the IMG tag? – Mecon May 28 '15 at 19:53
  • currently as "http://localhost:8080/something/getImg?id=2" – St.running May 28 '15 at 20:01
  • upd: after doin it like this: "http://localhost:8080/something/getImg2", it returns NullPointerException – St.running May 28 '15 at 20:14
  • finally, working! I'll post solution – St.running May 28 '15 at 20:40
  • cool.. by the way, I added my comments as an answer (just in case you feel like marking them as the accepted answer) – Mecon May 28 '15 at 20:44
  • Yes, I would ) They made me think in the right directions – St.running May 28 '15 at 20:45

2 Answers2

3

Images can't be (shouldn't be) inserted like data in HTML. An Image should be loaded by a URL.

  1. Make HTML be like this: img src="/something/getImg?id=123"
  2. Create a controller that accepts URL "something/getImg".
  3. In the Controller, return the Image by using Servlet's response.Outputstream

For each image you want to display, create an IMG html element. Each IMG's "src" attribute will point a specific URL for that image: ..getImage?id=111 , getImage?id=112, etc. The controller method will look for request parameter "id", and return the Image for that id.

Mecon
  • 977
  • 1
  • 6
  • 17
2

The broken image means the url to the image is wrong. Can you tell us what the value of href is for this image in your page.

kodeally
  • 15
  • 3
  • do you mean image filename? it is a byte array (byte []) which is stored as a BLOB in MYSQL. image service gets a list of Masterpieces, where two strings are name and comment and byte array is an image. Or you meant something else? – St.running May 26 '15 at 14:24
  • I would solve this a different way instead of returning the byte stream in the jsp page have the Masterpiece class return a url to an image e.g [spring-display-image-on-jsp-file](http://stackoverflow.com/questions/10066349/spring-display-image-on-jsp-file). – kodeally May 27 '15 at 08:55
  • Yes, It seems as an option, but inconvinient one. Here I need to present a list of images with comments, so naturally it would be good to get a list of Masterpieces and put in the model – St.running May 28 '15 at 14:13
  • 1
    You can still add the masterpiece into the model and add your descriptions and comments. The only change is you reference the image with a url and add a new controller to handle the browser fetching the image like in the answer provided. – kodeally May 28 '15 at 18:10
  • Well, yes. You and Mecon are right, now I get it and will try to implement. – St.running May 28 '15 at 18:18