generate a chart from a controller

2019-08-21 02:26发布

问题:

i use spring 3.0, in a jsp, i try to display data and a chart...

@Controller
@RequestMapping("/user.htm")
public class UserController {

@Autowired
private IUserService userService;

@RequestMapping(method = RequestMethod.GET)
public ModelAndView user(HttpServletRequest request,
    HttpServletResponse response) {

    ModelAndView modelAndView = new ModelAndView("user");
    modelAndView.addObject("statUser", userService.getStatUser());

    return modelAndView;
}

public void generateChart(HttpServletRequest request,
    HttpServletResponse response){
    try {
        AxisChart axisChart = userService.generateChart();
        ServletEncoderHelper.encodeJPEG13( axisChart, 1.0f, response );
    } catch (ChartDataException ex) {

    } catch (PropertyException ex) {

    } catch (IOException ex) {

    }

  }

}

in the jsp i try to display the chart with

<img src="generateChart"/>

i can see the information... so the get of the controller work fine, but the image is never displayed

so i don't know if i can use the same controller or need to create a new one only for creation of the image...

any idea?

回答1:

I've done something similer with Jfreechart, I ended up creating another chart controller with a mapping like @RequestMapping("/chart.jpg") and then link to it via <img src="cart.jpg"/>. In the controller then you have to set response.setHeader("Content-Type", "image/jpg");.

Edit: Here a example of mine (it's in groovy and it's a png, but it should help)

@RequestMapping("/chart.png")
def chart(HttpServletRequest request, HttpServletResponse response){
    JFreeChart chart = ChartFactory.createTimeSeriesChart(...)
    //fill & layout the chart
    def pngChart = EncoderUtil.encode(chart.createBufferedImage(600, 400), "png")
    response.setContentType("image/png");
    response.setContentLength(pngChart.length);
    response.getOutputStream().write(pngChart);
    response.getOutputStream().close();
}


回答2:

I am using the single interface for several report handlers. ModelAndView is always expected as a result. I think this is generic situation, when you need to process different reports and return data in different formats.

So, I resolved problem by extending AbstractView. Note: Code example loads file from the disk. You have to create byte array output stream using your own image generator and data represented in the model.

Example creating ModelAndView:

ModelAndView result = new ModelAndView();
result.setView(new ImageView());
result.addObject("chart_data_param1", "1");
result.addObject("chart_data_param2", "2");
result.addObject("chart_data_param3", "3");

Implementation of the View class:

public class ImageView extends AbstractView {

        public ImageView() {
            setContentType("image/png");
        }

        @Override
        protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
            ByteArrayOutputStream baos = createTemporaryOutputStream();
            byte[] img = FileUtils.readFileToByteArray(new File("<some-file-path>"));
            baos.write(img, 0, img.length);
            baos.close();
            writeToResponse(response, baos);
        }
    }