/webportal/src/main/java/org/ala/spatial/wms/WMSService.java
Java | 580 lines | 476 code | 59 blank | 45 comment | 121 complexity | 656de807df4a2a695bf66b2bf91339cf MD5 | raw file
1/* 2 * To change this template, choose Tools | Templates 3 * and open the template in the editor. 4 */ 5package org.ala.spatial.wms; 6 7import au.org.emii.portal.config.ConfigurationLoaderStage1; 8import au.org.emii.portal.util.SessionPrint; 9import java.awt.AlphaComposite; 10import java.awt.BasicStroke; 11import java.awt.Color; 12import java.awt.Graphics2D; 13import java.awt.Image; 14import java.awt.RenderingHints; 15import java.awt.image.BufferedImage; 16import java.awt.image.BufferedImageOp; 17import java.io.BufferedReader; 18import java.io.FileInputStream; 19import java.io.IOException; 20import java.io.InputStreamReader; 21import java.io.OutputStream; 22import java.io.RandomAccessFile; 23import java.io.UnsupportedEncodingException; 24import java.net.URL; 25import java.net.URLDecoder; 26import java.util.ArrayList; 27import java.util.logging.Level; 28import java.util.logging.Logger; 29import javax.imageio.ImageIO; 30import javax.imageio.ImageReader; 31import javax.imageio.stream.ImageInputStream; 32import javax.inject.Inject; 33import javax.servlet.ServletOutputStream; 34import javax.servlet.http.HttpServletRequest; 35import javax.servlet.http.HttpServletResponse; 36import org.ala.spatial.data.Facet; 37import org.ala.spatial.data.FacetCache; 38import org.ala.spatial.data.Legend; 39import org.ala.spatial.data.QueryField; 40import org.ala.spatial.util.CommonData; 41import org.ala.spatial.util.Util; 42import org.springframework.stereotype.Controller; 43import org.springframework.web.bind.annotation.RequestMapping; 44import org.springframework.web.bind.annotation.RequestMethod; 45import org.springframework.web.bind.annotation.RequestParam; 46import org.springframework.web.bind.annotation.ResponseBody; 47 48/** 49 * 50 * @author Adam 51 */ 52@Controller 53public class WMSService { 54 final static int HIGHLIGHT_RADIUS = 3; 55 @Inject 56 private FacetCache facetCache; 57 58 /* 59 http://spatial.ala.org.au/geoserver/wms/reflect?styles=&format=image/png& 60 layers=ALA:occurrences&transparent=true& 61 CQL_FILTER=speciesconceptid='urn:lsid:biodiversity.org.au:afd.taxon:cd149740-87b2-4da2-96dc-e1aa1f693438'&SRS=EPSG%3A900913& 62 ENV=color%3A1dd183%3Bname%3Acircle%3Bsize%3A8%3Bopacity%3A0.8& 63 VERSION=1.1.0& 64 SERVICE=WMS&REQUEST=GetMap& 65 EXCEPTIONS=application%2Fvnd.ogc.se_inimage& 66 BBOX=15654303.7292,-1408886.9659,15810846.7631,-1252343.932& 67 WIDTH=256& 68 HEIGHT=256 69 * 70 */ 71 72 @RequestMapping(value = "/wms/reflect", method = RequestMethod.GET) 73 public void getPointsMap( 74 @RequestParam(value = "CQL_FILTER", required = false, defaultValue = "") String cql_filter, 75 @RequestParam(value = "ENV", required = false, defaultValue = "") String env, 76 @RequestParam(value = "BBOX", required = false, defaultValue = "") String bboxString, 77 @RequestParam(value = "WIDTH", required = false, defaultValue = "") String widthString, 78 @RequestParam(value = "HEIGHT", required = false, defaultValue = "") String heightString, 79 HttpServletRequest request, HttpServletResponse response) { 80 81 response.setHeader("Cache-Control", "max-age=86400"); //age == 1 day 82 response.setContentType("image/png"); //only png images generated 83 84 int width = 256, height = 256; 85 try { 86 width = Integer.parseInt(widthString); 87 height = Integer.parseInt(heightString); 88 } catch (Exception e) { 89 e.printStackTrace(); 90 } 91 92 try { 93 env = URLDecoder.decode(env, "UTF-8"); 94 } catch (UnsupportedEncodingException ex) { 95 Logger.getLogger(WMSService.class.getName()).log(Level.SEVERE, null, ex); 96 } 97 int red = 0, green = 0, blue = 0, alpha = 0; 98 String name = "circle"; 99 int size = 4; 100 boolean uncertainty = false; 101 String highlight = null; 102 String colourMode = null; 103 for (String s : env.split(";")) { 104 String[] pair = s.split(":"); 105 if (pair[0].equals("color")) { 106 while (pair[1].length() < 6) { 107 pair[1] = "0" + pair[1]; 108 } 109 red = Integer.parseInt(pair[1].substring(0, 2), 16); 110 green = Integer.parseInt(pair[1].substring(2, 4), 16); 111 blue = Integer.parseInt(pair[1].substring(4), 16); 112 } else if (pair[0].equals("name")) { 113 name = pair[1]; 114 } else if (pair[0].equals("size")) { 115 size = Integer.parseInt(pair[1]); 116 } else if (pair[0].equals("opacity")) { 117 alpha = (int) (255 * Double.parseDouble(pair[1])); 118// } else if (pair[0].equals("uncertainty")) { 119// uncertainty = true; 120 } else if (pair[0].equals("sel")) { 121 try { 122 highlight = URLDecoder.decode(s.substring(4),"UTF-8").replace("%3B",";"); 123 } catch (Exception e) {} 124 } else if (pair[0].equals("colormode")) { 125 colourMode = pair[1]; 126 } 127 } 128 129 double[] bbox = new double[4]; 130 int i; 131 i = 0; 132 for (String s : bboxString.split(",")) { 133 try { 134 bbox[i] = Double.parseDouble(s); 135 i++; 136 } catch (Exception e) { 137 e.printStackTrace(); 138 } 139 } 140 try { 141 142 //adjust bbox extents with half pixel width/height 143 double pixelWidth = (bbox[2] - bbox[0]) / width; 144 double pixelHeight = (bbox[3] - bbox[1]) / height; 145 bbox[0] += pixelWidth / 2; 146 bbox[2] -= pixelWidth / 2; 147 bbox[1] += pixelHeight / 2; 148 bbox[3] -= pixelHeight / 2; 149 150 //offset for points bounding box by size 151 double xoffset = (bbox[2] - bbox[0]) / (double) width * (size + (highlight!=null?HIGHLIGHT_RADIUS*2 + size * 0.2:0) + 5); 152 double yoffset = (bbox[3] - bbox[1]) / (double) height * (size + (highlight!=null?HIGHLIGHT_RADIUS*2 + size * 0.2:0) + 5); 153 154 //check offset for points bb by maximum uncertainty (?? 30k ??) 155 if (uncertainty) { 156 double xuoffset = 30000; 157 double yuoffset = 30000; 158 if (xoffset < xuoffset) { 159 xoffset = xuoffset; 160 } 161 if (yoffset < yuoffset) { 162 yoffset = yuoffset; 163 } 164 } 165 166 //adjust offset for pixel height/width 167 xoffset += pixelWidth; 168 yoffset += pixelHeight; 169 170 double[][] bb = {{Utils.convertMetersToLng(bbox[0] - xoffset), Utils.convertMetersToLat(bbox[1] - yoffset)}, {Utils.convertMetersToLng(bbox[2] + xoffset), Utils.convertMetersToLat(bbox[3] + yoffset)}}; 171 172 double[] pbbox = new double[4]; //pixel bounding box 173 pbbox[0] = Utils.convertLngToPixel(Utils.convertMetersToLng(bbox[0])); 174 pbbox[1] = Utils.convertLatToPixel(Utils.convertMetersToLat(bbox[1])); 175 pbbox[2] = Utils.convertLngToPixel(Utils.convertMetersToLng(bbox[2])); 176 pbbox[3] = Utils.convertLatToPixel(Utils.convertMetersToLat(bbox[3])); 177 178 String lsid = null; 179 int p1 = 0; 180 int p2 = cql_filter.indexOf('&', p1 + 1); 181 if (p2 < 0) { 182 p2 = cql_filter.indexOf(';', p1 + 1); 183 } 184 if (p2 < 0) { 185 p2 = cql_filter.length(); 186 } 187 if (p1 >= 0) { 188 lsid = cql_filter.substring(0, p2); 189 } 190 191 double[] points = null; 192 ArrayList<QueryField> listHighlight = null; 193 QueryField colours = null; 194 double[] pointsBB = null; 195 Facet facet = null; 196 String[] facetFields = null; 197 if (highlight != null && !(colourMode != null && colourMode.equals("grid"))) { 198 facet = Facet.parseFacet(highlight); 199 facetFields = facet.getFields(); 200 listHighlight = new ArrayList<QueryField>(); 201 } 202 if (lsid != null) { 203 Object[] data = (Object[]) RecordsLookup.getData(lsid); 204 points = (double[]) data[0]; 205 pointsBB = (double[]) data[2]; 206 207 if (points == null || points.length == 0 208 || pointsBB[0] > bb[1][0] || pointsBB[2] < bb[0][0] 209 || pointsBB[1] > bb[1][1] || pointsBB[3] < bb[0][1]) { 210 setImageBlank(response); 211 return; 212 } 213 214 ArrayList<QueryField> fields = (ArrayList<QueryField>) data[1]; 215 216 for (int j = 0; j < fields.size(); j++) { 217 if (facet != null) { 218 for (int k = 0; k < facetFields.length; k++) { 219 if (facetFields[k].equals(fields.get(j).getName())) { 220 listHighlight.add(fields.get(j)); 221 } 222 } 223 } 224 if (colourMode != null) { 225 if (fields.get(j).getName().equals(colourMode)) { 226 colours = fields.get(j); 227 } 228 } 229 } 230 } 231 232 /* TODO: make this a copy instead of create */ 233 BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 234 Graphics2D g = (Graphics2D) img.getGraphics(); 235 g.setColor(new Color(0, 0, 0, 0)); 236 g.fillRect(0, 0, width, height); 237 238 g.setColor(new Color(red, green, blue, alpha)); 239 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 240 int x, y; 241 int pointWidth = size * 2 + 1; 242 double width_mult = (width / (pbbox[2] - pbbox[0])); 243 double height_mult = (height / (pbbox[1] - pbbox[3])); 244 245 if (colourMode != null && colourMode.equals("grid")) { 246 int divs = 16; 247 double grid_width_mult = (width / (pbbox[2] - pbbox[0])) / (256 / divs); 248 double grid_height_mult = (height / (pbbox[1] - pbbox[3])) / (256 / divs); 249 int[][] gridCounts = new int[divs][divs]; 250 for (i = 0; i < points.length; i += 2) { 251 x = (int) ((Utils.convertLngToPixel(points[i]) - pbbox[0]) * grid_width_mult); 252 y = (int) ((Utils.convertLatToPixel(points[i + 1]) - pbbox[3]) * grid_height_mult); 253 if (x >= 0 && x < divs && y >= 0 && y < divs) { 254 gridCounts[x][y]++; 255 } 256 } 257 int xstep = 256 / divs; 258 int ystep = 256 / divs; 259 for (x = 0; x < divs; x++) { 260 for (y = 0; y < divs; y++) { 261 int v = gridCounts[x][y]; 262 if (v > 0) { 263 if (v > 500) { 264 v = 500; 265 } 266 int colour = Legend.getLinearColour(v, 0, 500, 0xFFFFFF00, 0xFFFF0000); 267 g.setColor(new Color(colour)); 268 g.fillRect(x * xstep, y * ystep, xstep, ystep); 269 } 270 } 271 } 272 } else { 273 //circle type 274 if (name.equals("circle")) { 275 if (colours == null) { 276 for (i = 0; i < points.length; i += 2) { 277 if (points[i] >= bb[0][0] && points[i] <= bb[1][0] 278 && points[i + 1] >= bb[0][1] && points[i + 1] <= bb[1][1]) { 279 x = (int) ((Utils.convertLngToPixel(points[i]) - pbbox[0]) * width_mult); 280 y = (int) ((Utils.convertLatToPixel(points[i + 1]) - pbbox[3]) * height_mult); 281 g.fillOval(x - size, y - size, pointWidth, pointWidth); 282 } 283 } 284 } else { 285 int prevColour = -1; //!= colours[0] 286 g.setColor(new Color(prevColour)); 287 for (i = 0; i < points.length; i += 2) { 288 if (points[i] >= bb[0][0] && points[i] <= bb[1][0] 289 && points[i + 1] >= bb[0][1] && points[i + 1] <= bb[1][1]) { 290 int thisColour = colours.getColour(i / 2); 291 if (thisColour != prevColour) { 292 g.setColor(new Color(thisColour)); 293 prevColour = thisColour; 294 } 295 x = (int) ((Utils.convertLngToPixel(points[i]) - pbbox[0]) * width_mult); 296 y = (int) ((Utils.convertLatToPixel(points[i + 1]) - pbbox[3]) * height_mult); 297 g.fillOval(x - size, y - size, pointWidth, pointWidth); 298 } 299 } 300 } 301 } 302 303 if (highlight != null && facet != null) { 304 g.setStroke(new BasicStroke(2)); 305 g.setColor(new Color(255, 0, 0, 255)); 306 int sz = size + HIGHLIGHT_RADIUS; 307 int w = sz * 2 + 1; 308 for (i = 0; i < points.length; i += 2) { 309 if (points[i] >= bb[0][0] && points[i] <= bb[1][0] 310 && points[i + 1] >= bb[0][1] && points[i + 1] <= bb[1][1]) { 311 if (facet.isValid(listHighlight, i / 2)) { 312 x = (int) ((Utils.convertLngToPixel(points[i]) - pbbox[0]) * width_mult); 313 y = (int) ((Utils.convertLatToPixel(points[i + 1]) - pbbox[3]) * height_mult); 314 g.drawOval(x - sz, y - sz, w, w); 315 } 316 } 317 } 318 } 319 } 320 321 g.dispose(); 322 323 try { 324 OutputStream os = response.getOutputStream(); 325 ImageIO.write(img, "png", os); 326 os.flush(); 327 os.close(); 328 } catch (IOException e) { 329 e.printStackTrace(); 330 } 331 } catch (Exception e) { 332 e.printStackTrace(); 333 } 334 335 //System.out.println("[wms tile: " + (System.currentTimeMillis() - start) + "ms]"); 336 } 337 //256x256 transparent image 338 static Object blankImageObject = new Object(); 339 static byte[] blankImageBytes = null; 340 341 private void setImageBlank(HttpServletResponse response) { 342 if (blankImageBytes == null && blankImageObject != null) { 343 synchronized (blankImageObject) { 344 if (blankImageBytes == null) { 345 try { 346 RandomAccessFile raf = new RandomAccessFile(WMSService.class.getResource("/blank.png").getFile(), "r"); 347 blankImageBytes = new byte[(int) raf.length()]; 348 raf.read(blankImageBytes); 349 raf.close(); 350 } catch (IOException ex) { 351 Logger.getLogger(WMSService.class.getName()).log(Level.SEVERE, null, ex); 352 } 353 } 354 } 355 } 356 if (blankImageObject != null) { 357 response.setContentType("image/png"); 358 try { 359 ServletOutputStream outStream = response.getOutputStream(); 360 outStream.write(blankImageBytes); 361 outStream.flush(); 362 outStream.close(); 363 } catch (IOException ex) { 364 Logger.getLogger(WMSService.class.getName()).log(Level.SEVERE, null, ex); 365 } 366 } 367 } 368 369 @RequestMapping(value = "/occurrences", method = RequestMethod.GET) 370 public 371 @ResponseBody 372 String getOccurrencesUploaded(HttpServletRequest request) { 373 String q = request.getParameter("q"); 374 String box = request.getParameter("box"); 375 int start = Integer.parseInt(request.getParameter("start")); 376 377 String[] bb = box.split(","); 378 379 double long1 = Double.parseDouble(bb[0]); 380 double lat1 = Double.parseDouble(bb[1]); 381 double long2 = Double.parseDouble(bb[2]); 382 double lat2 = Double.parseDouble(bb[3]); 383 384 Object[] data = (Object[]) RecordsLookup.getData(q); 385 386 int count = 0; 387 String record = null; 388 if (data != null) { 389 double[] points = (double[]) data[0]; 390 ArrayList<QueryField> fields = (ArrayList<QueryField>) data[1]; 391 double[] pointsBB = (double[]) data[2]; 392 String metadata = (String) data[3]; 393 394 if (points == null || points.length == 0 395 || pointsBB[0] > long2 || pointsBB[2] < long1 396 || pointsBB[1] > lat2 || pointsBB[3] < lat1) { 397 return null; 398 } else { 399 for (int i = 0; i < points.length; i += 2) { 400 if (points[i] >= long1 && points[i] <= long2 401 && points[i + 1] >= lat1 && points[i + 1] <= lat2) { 402 if (count == start) { 403 StringBuilder sb = new StringBuilder(); 404 for (QueryField qf : fields) { 405 if (sb.length() == 0) { 406 sb.append("{\"totalRecords\":<totalCount>,\"occurrences\":[{"); 407 } else { 408 sb.append(","); 409 } 410 sb.append("\"").append(qf.getDisplayName()).append("\":\""); 411 sb.append(qf.getAsString(i / 2).replace("\"", "\\\"")).append("\""); 412 } 413 sb.append("}]"); 414 sb.append(",\"metadata\":\""); 415 sb.append(metadata); 416 sb.append("\""); 417 sb.append("}"); 418 record = sb.toString(); 419 } 420 count++; 421 } 422 } 423 } 424 } 425 426 if (record != null) { 427 record = record.replace("<totalCount>", String.valueOf(count)); 428 } 429 430 return record; 431 } 432 433 @RequestMapping(value = "/admin/reloadconfig", method = RequestMethod.GET) 434 @ResponseBody 435 public String reloadConfig() { 436 //signal for reload 437 ConfigurationLoaderStage1.loaders.get(0).interrupt(); 438 439 //reload the facet cache 440 facetCache.reloadCache(); 441 442 //return summary 443 StringBuilder html = new StringBuilder(); 444 445 //was it successful? 446 447 return html.toString(); 448 } 449 450 @RequestMapping(value = "/image2", method = RequestMethod.GET) 451 public void image2( 452 @RequestParam(value = "type", required = false, defaultValue = "jpg") String type, 453 @RequestParam(value = "extents", required = true) String bbox, 454 @RequestParam(value = "pixelwidth", required = false, defaultValue = "800") Integer width, 455 @RequestParam(value = "psize", required = false, defaultValue = "3") Integer pointSize, 456 @RequestParam(value = "pcolour", required = false, defaultValue = "FF0000") String pointColour, 457 @RequestParam(value = "popacity", required = false, defaultValue = "0.6") Double pointOpacity, 458 @RequestParam(value = "basemap", required = false, defaultValue = "world") String basemap, 459 @RequestParam(value = "legend", required = false, defaultValue = "off") String legend, 460 @RequestParam(value = "bs", required = false) String biocacheServer, 461 462 HttpServletRequest request, HttpServletResponse response) throws Exception { 463 464 try { 465 String [] bb = bbox.split(","); 466 int pminx = Utils.convertLngToPixel(Double.parseDouble(bb[0])); 467 int pminy = Utils.convertLatToPixel(Double.parseDouble(bb[1])); 468 int pmaxx = Utils.convertLngToPixel(Double.parseDouble(bb[2])); 469 int pmaxy = Utils.convertLatToPixel(Double.parseDouble(bb[3])); 470 int height = (int) Math.round(width * ((pminy - pmaxy) / (double)(pmaxx - pminx))); 471 472 double [] extents = Util.transformBbox4326To900913(Double.parseDouble(bb[0]),Double.parseDouble(bb[1]),Double.parseDouble(bb[2]),Double.parseDouble(bb[3])); 473 474 //"http://biocache.ala.org.au/ws/webportal/wms/reflect? 475 //q=macropus&ENV=color%3Aff0000%3Bname%3Acircle%3Bsize%3A3%3Bopacity%3A1 476 //&BBOX=12523443.0512,-2504688.2032,15028131.5936,0.33920000120997&WIDTH=256&HEIGHT=256"); 477 String speciesAddress = ((biocacheServer == null) ? CommonData.biocacheServer : biocacheServer) 478 + "/webportal/wms/reflect?" 479 + "ENV=color%3A" + pointColour 480 + "%3Bname%3Acircle%3Bsize%3A" + pointSize 481 + "%3Bopacity%3A" + pointOpacity 482 + "&BBOX=" + extents[0] + "," + extents[1] + "," + extents[2] + "," + extents[3] 483 + "&WIDTH=" + width + "&HEIGHT=" + height 484 + "&" + request.getQueryString(); 485 System.out.println(speciesAddress); 486 URL speciesURL = new URL(speciesAddress); 487 488 BufferedImage speciesImage = ImageIO.read(speciesURL); 489 490 //"http://spatial.ala.org.au/geoserver/wms/reflect? 491 //LAYERS=ALA%3Aworld&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES= 492 //&FORMAT=image%2Fjpeg&SRS=EPSG%3A900913&BBOX=12523443.0512,-1252343.932,13775787.3224,0.33920000004582&WIDTH=256&HEIGHT=256" 493 String basemapAddress = CommonData.geoServer + "/wms/reflect?" 494 + "LAYERS=ALA%3A" + basemap 495 + "&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=" 496 + "&FORMAT=image%2Fjpeg&SRS=EPSG%3A900913" 497 + "&BBOX=" + extents[0] + "," + extents[1] + "," + extents[2] + "," + extents[3] 498 + "&WIDTH=" + width + "&HEIGHT=" + height 499 + (!legend.equals("off")?"&format_options=layout:legend":""); 500 System.out.println(basemapAddress); 501 URL basemapURL = new URL(basemapAddress); 502 BufferedImage basemapImage = ImageIO.read(basemapURL); 503 504 BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 505 Graphics2D combined = (Graphics2D) img.getGraphics(); 506 507 combined.drawImage(basemapImage, 0, 0, Color.WHITE, null); 508 combined.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f)); 509 combined.drawImage(speciesImage, null, 0, 0); 510 combined.dispose(); 511 512 //response.setHeader("Cache-Control", "max-age=3600"); //age == 1hr 513 514 if (type.equalsIgnoreCase("png")) { 515 response.setContentType("image/png"); 516 OutputStream os = response.getOutputStream(); 517 ImageIO.write(img, type, os); 518 os.close(); 519 } else { 520 //handle jpeg + BufferedImage.TYPE_INT_ARGB 521 BufferedImage img2; 522 Graphics2D c2; 523 (c2 = (Graphics2D) (img2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)).getGraphics()).drawImage(img, 0,0,Color.WHITE, null); 524 c2.dispose(); 525 OutputStream os = response.getOutputStream(); 526 ImageIO.write(img2, type, os); 527 os.close(); 528 response.setContentType("image/jpeg"); 529 } 530 }catch (Exception e) { 531 e.printStackTrace(); 532 } 533 } 534 535 @RequestMapping(value = "/image", method = RequestMethod.GET) 536 public void image( 537 @RequestParam(value = "type", required = false, defaultValue = "jpg") String type, 538 @RequestParam(value = "bbox", required = false, defaultValue = "0,0,0,0") String bbox, 539 @RequestParam(value = "width", required = false, defaultValue = "800") String width, 540 @RequestParam(value = "height", required = false, defaultValue = "640") String height, 541 @RequestParam(value = "basemap", required = false, defaultValue = "outline") String basemap, 542 543 HttpServletRequest request, HttpServletResponse response) throws IOException { 544 545 //zoom (minlong, minlat, maxlong, maxlat, lhs width, basemap 546 String zoom = "n" + bbox + ",0," + basemap; 547 548 //unique id 549 String uid = String.valueOf(System.currentTimeMillis()); 550 String htmlpth = CommonData.print_output_path; 551 String htmlurl = CommonData.print_output_url; 552 553 SessionPrint sp = new SessionPrint( 554 CommonData.webportalServer, "&" + request.getQueryString(), 555 height, width, 556 htmlpth, htmlurl, uid, 557 zoom, "", 0, type); 558 559 sp.print(); 560 561 response.setHeader("Cache-Control", "max-age=86400"); //age == 1 day 562 if (type.equalsIgnoreCase("png")) { 563 response.setContentType("image/png"); 564 } else if (type.equalsIgnoreCase("pdf")) { 565 response.setContentType("application/pdf"); 566 } else { 567 response.setContentType("image/jpeg"); 568 } 569 570 OutputStream os = response.getOutputStream(); 571 FileInputStream fis = new FileInputStream(sp.getImageFilename()); 572 byte [] buffer = new byte[1024]; 573 int n; 574 while((n = fis.read(buffer)) > 0) { 575 os.write(buffer, 0, n); 576 } 577 fis.close(); 578 os.close(); 579 } 580}