স্প্রিং এমভিসি: কীভাবে @ রেসপোনসবডিতে চিত্রটি ফিরবেন?


142

আমি byte[]ডিবি থেকে চিত্রের ডেটা (হিসাবে ) পাচ্ছি । এই চিত্রটি কীভাবে ফিরে আসবে @ResponseBody?

সম্পাদনা

আমি পদ্ধতি প্যারামিটার হিসাবে @ResponseBodyব্যবহার না করে এটি করেছি HttpServletResponse:

@RequestMapping("/photo1")
public void photo(HttpServletResponse response) throws IOException {
    response.setContentType("image/jpeg");
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    IOUtils.copy(in, response.getOutputStream());
}

ব্যবহার @ResponseBodyনিবন্ধিত সঙ্গে org.springframework.http.converter.ByteArrayHttpMessageConverterকনভার্টার হিসাবে @Sid বলেন আমার জন্য কাজ করে না :(।

@ResponseBody
@RequestMapping("/photo2")
public byte[] testphoto() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    return IOUtils.toByteArray(in);
}

উত্তর:


97

যদি আপনি ৩.১ এর স্প্রিং সংস্করণ বা তার থেকেও নতুন ব্যবহার করেন তবে আপনি টীকাতে "উত্পাদন" নির্দিষ্ট করতে পারেন @RequestMapping। নীচে উদাহরণ বাক্স বাইরে আমার জন্য কাজ করে। আপনার যদি ওয়েব এমভিসি সক্ষম ( @EnableWebMvc) সক্রিয় করা থাকে তবে নিবন্ধকার রূপান্তরকারী বা অন্য কোনও কিছুর প্রয়োজন নেই ।

@ResponseBody
@RequestMapping(value = "/photo2", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] testphoto() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    return IOUtils.toByteArray(in);
}

77

স্প্রিং ৪.১ এবং তারপরে, আপনি কোনও অতিরিক্ত নির্ভরতা ছাড়াই বেশ কিছু সহজে (যেমন ছবি, পিডিএফ, ডকুমেন্টস, জারস, জিপস ইত্যাদি) ফিরে আসতে পারেন। উদাহরণস্বরূপ, মঙ্গোডিবি গ্রিডেএসএফ থেকে কোনও ব্যবহারকারীর প্রোফাইল ছবি ফেরত দেওয়ার জন্য নিম্নলিখিত পদ্ধতি হতে পারে:

@RequestMapping(value = "user/avatar/{userId}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<InputStreamResource> downloadUserAvatarImage(@PathVariable Long userId) {
    GridFSDBFile gridFsFile = fileService.findUserAccountAvatarById(userId);

    return ResponseEntity.ok()
            .contentLength(gridFsFile.getLength())
            .contentType(MediaType.parseMediaType(gridFsFile.getContentType()))
            .body(new InputStreamResource(gridFsFile.getInputStream()));
}

বিষয়গুলি লক্ষ্য করুন:

  • রিটার্নের ধরণ হিসাবে ইনপুট স্ট্রিম রিসোর্সের সাথে প্রতিক্রিয়াশক্তি

  • রেসপন্সএন্টিটি বিল্ডার স্টাইল তৈরি

এই পদ্ধতির সাহায্যে আপনাকে এইচটিপিএস সার্লেটরেসপোনসে অটোয়ারিং, আইওএক্সেপশন নিক্ষেপ বা চারপাশের স্ট্রিম ডেটা অনুলিপি করার বিষয়ে চিন্তা করতে হবে না।


1
এটি নিম্নলিখিত ব্যতিক্রমটি ছুঁড়েছে, আপনি কীভাবে মাইআইনপুটস্ট্রিমকে সিরিয়াল করছেন ?: সামগ্রী লিখতে পারেন নি: com.mongodb.gridfs.GridFSDBFile class মাইআইনপুটস্ট্রিম
নেস্টর

এটি সম্ভবত আপনি যা করতে পারছেন তার উদাহরণ হিসাবে, গ্রিডএফএসডিবিফিল.জিটইনপুটস্ট্রিম () সহ মঙ্গো-জাভা-ড্রাইভার 3.0.3 মাই ইনপুটস্ট্রিম নামে একটি বেনাম শ্রেণি ফিরিয়ে দেয় না। আমি আপনার সংস্করণগুলি পরীক্ষা করব - সম্ভবত আপডেট?
জেমস বর্ডেন

4
আমি পছন্দ করি এটি কীভাবে পুরো জিনিসটিকে মেমরির অনুলিপি না করে ফাইলটি প্রবাহিত করে। আরও দেখুন stackoverflow.com/questions/20333394/...
Wim Deblauwe

60

একটি নিবন্ধকরণ ছাড়াও ByteArrayHttpMessageConverter, আপনি এর ResponseEntityপরিবর্তে একটি ব্যবহার করতে পারেন @ResponseBody। নিম্নলিখিত কোডটি আমার পক্ষে কাজ করে:

@RequestMapping("/photo2")
public ResponseEntity<byte[]> testphoto() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");

    final HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.IMAGE_PNG);

    return new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
}

16

স্প্রিং ৩.১.x এবং ৩.২.x ব্যবহার করে আপনার এটি করা উচিত:

নিয়ামক পদ্ধতি:

@RequestMapping("/photo2")
public @ResponseBody byte[] testphoto() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    return IOUtils.toByteArray(in);
}

সার্ভলেট-কনটেক্সট.এক্সএমএল ফাইলে এমভিসি টিকা:

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>image/jpeg</value>
                    <value>image/png</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

13

এখানে কয়েকটি উত্তর ছাড়াও কয়েকটি পয়েন্টার (স্প্রিং 4.1)।

আপনার নিজের ওয়েবমেভসি কনফিগটিতে ResponseEntityআপনার @ResponseBodyকাজের মধ্যে ভালভাবে কনফিগার করা কোনও মেসেজকভার্টার নেই Inc

যদি আপনি না, অর্থাত আপনি যদি একটি আছে MappingJackson2HttpMessageConverterকনফিগার (আমার মত) ব্যবহার করে ResponseEntityআয় একটি org.springframework.http.converter.HttpMessageNotWritableException

এই ক্ষেত্রে শুধুমাত্র কাজ সমাধান মোড়ানো হয় byte[]মধ্যে @ResponseBodyনিম্নরূপ:

@RequestMapping(value = "/get/image/{id}", method=RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
public @ResponseBody byte[] showImageOnId(@PathVariable("id") String id) {
    byte[] b = whatEverMethodUsedToObtainBytes(id);
    return b;
}

এক্ষেত্রে আপনার ওয়েবএমভিসি কনফিগে বার্তা রূপান্তরকারীগুলিকে সঠিকভাবে কনফিগার করতে (এবং একটি যোগ করুন ByteArrayHttpMessageConverer) মনে রাখবেন:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(mappingJackson2HttpMessageConverter());
    converters.add(byteArrayHttpMessageConverter());
}

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setObjectMapper(objectMapper);
    return converter;
}

@Bean
public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
    ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
    arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
    return arrayHttpMessageConverter;
}

private List<MediaType> getSupportedMediaTypes() {
    List<MediaType> list = new ArrayList<MediaType>();
    list.add(MediaType.IMAGE_JPEG);
    list.add(MediaType.IMAGE_PNG);
    list.add(MediaType.APPLICATION_OCTET_STREAM);
    return list;
}

6

আপনার আবেদনের প্রসঙ্গে একটি টীকাগুলি মেঠোহ্যান্ডলার অ্যাডাপ্টার এবং রেজিস্টারবাইটিআরএইচটিপি ম্যাসেজ কনভার্টার ঘোষণা করুন:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="messageConverters">
    <util:list>
      <bean id="byteArrayMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
    </util:list>
  </property>
</bean> 

হ্যান্ডলার পদ্ধতিতেও আপনার প্রতিক্রিয়ার জন্য উপযুক্ত সামগ্রী প্রকার সেট করুন।


@ জিসিংহফস শীর্ষ উত্তরটি দেখুন।
পাইম্যানখ

6
 @RequestMapping(value = "/get-image",method = RequestMethod.GET)
public ResponseEntity<byte[]> getImage() throws IOException {
    RandomAccessFile f = new RandomAccessFile("/home/vivex/apache-tomcat-7.0.59/tmpFiles/1.jpg", "r");
    byte[] b = new byte[(int)f.length()];
    f.readFully(b);
    final HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.IMAGE_PNG);


    return new ResponseEntity<byte[]>(b, headers, HttpStatus.CREATED);



}

আমার জন্য কাজ।


5

আমি এই এক পছন্দ:

private ResourceLoader resourceLoader = new DefaultResourceLoader();

@ResponseBody
@RequestMapping(value = "/{id}",  produces = "image/bmp")
public Resource texture(@PathVariable("id") String id) {
    return resourceLoader.getResource("classpath:images/" + id + ".bmp");
}

আপনার যা ইমেজ ফর্ম্যাট আছে তা মিডিয়া টাইপ পরিবর্তন করুন।


1
ভাল কল ResourceLoader, তবে আপনার উদাহরণ হিসাবে বাহ্যিক ইনপুট থেকে একটি পথের
qerub

3

এটি আমার জন্য স্প্রিং 4-এ কাজ করে।

@RequestMapping(value = "/image/{id}", method = RequestMethod.GET)
public void findImage(@PathVariable("id") String id, HttpServletResponse resp){

        final Foto anafoto = <find object>
        resp.reset();
        resp.setContentType(MediaType.IMAGE_JPEG_VALUE);
        resp.setContentLength(anafoto.getImage().length);

        final BufferedInputStream in = new BufferedInputStream(new ByteArrayInputStream(anafoto.getImageInBytes()));

        try {
            FileCopyUtils.copy(in, resp.getOutputStream());
            resp.flushBuffer();
        } catch (final IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

}

2

কোনও উত্তর আমার পক্ষে কাজ করে নি, তাই আমি এটি এর মতো করে পরিচালনা করতে পেরেছি:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("your content type here"));
headers.set("Content-Disposition", "attachment; filename=fileName.jpg");
headers.setContentLength(fileContent.length);
return new ResponseEntity<>(fileContent, headers, HttpStatus.OK);

Content-Dispositionশিরোনাম সেট করা হচ্ছে আমি @ResponseBodyআমার পদ্ধতিতে টীকা সহ ফাইলটি ডাউনলোড করতে সক্ষম হয়েছি।


1

আমি স্প্রিং বুট এবং পেয়ারা দিয়ে এটিই করি:

@RequestMapping(value = "/getimage", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public void getImage( HttpServletResponse response ) throws IOException
{
    ByteStreams.copy( getClass().getResourceAsStream( "/preview-image.jpg" ), response.getOutputStream() );
}

1

প্রতিক্রিয়াতে আপনার মিডিয়া প্রকারটি নির্দিষ্ট করা উচিত। আমি উত্পাদিত = মিডিয়া টাইপ.আইএমপিজেজেপিজি_ভিউএলইউ সহ একটি @ গেটম্যাপিং টীকাটি ব্যবহার করছি। @ রিকোয়েস্টম্যাপিং একই কাজ করবে।

@GetMapping(value="/current/chart",produces = MediaType.IMAGE_JPEG_VALUE)
@ResponseBody
public byte[] getChart() {
    return ...;
}

মিডিয়া টাইপ ব্যতীত, আসলে কী ফিরে এসেছে তা অনুমান করা শক্ত (কোড, ব্রাউজার এবং অবশ্যই স্প্রিং নিজেই পড়েন এমন কাউকে অন্তর্ভুক্ত করা হয়েছে)। একটি বাইট [] কেবল নির্দিষ্ট নয়। বাইট [] থেকে মিডিয়ার ধরণ নির্ধারণের একমাত্র উপায় হ'ল আশেপাশে স্নিগ্ধ এবং অনুমান করা।

মিডিয়া টাইপ সরবরাহ করা কেবল সেরা অনুশীলন


এটি আমার জন্য স্প্রিং বুট ২.x এ কাজ করে ভাগ করার জন্য আপনাকে ধন্যবাদ।
অ্যাটমোসিয়ান

0

বসন্ত 4 এ এটি খুব সহজ আপনার মটরশুটিগুলিতে কোনও পরিবর্তন করার দরকার নেই। কেবলমাত্র আপনার রিটার্নের প্রকারটি @ রেসপন্সবডিতে চিহ্নিত করুন।

উদাহরণ: -

@RequestMapping(value = "/image/{id}")
    public @ResponseBody
    byte[] showImage(@PathVariable Integer id) {
                 byte[] b;
        /* Do your logic and return 
               */
        return b;
    }

1
আমি এটির সাথে সমস্যাটি হ'ল বিষয়বস্তুর ধরণটি সঠিকভাবে সেট করা নেই।
ETL

0

আমি মনে করি ফাইল আপলোড সঞ্চয় করতে এবং সেই ফাইলটি পেতে আপনার সম্ভবত কোনও পরিষেবা প্রয়োজন। এখান থেকে আরও বিশদ পরীক্ষা করুন

1) স্টোরেজ সেভিস তৈরি করুন

@Service
public class StorageService {

Logger log = LoggerFactory.getLogger(this.getClass().getName());
private final Path rootLocation = Paths.get("upload-dir");

public void store(MultipartFile file) {
    try {
        Files.copy(file.getInputStream(), this.rootLocation.resolve(file.getOriginalFilename()));
    } catch (Exception e) {
        throw new RuntimeException("FAIL!");
    }
}

public Resource loadFile(String filename) {
    try {
        Path file = rootLocation.resolve(filename);
        Resource resource = new UrlResource(file.toUri());
        if (resource.exists() || resource.isReadable()) {
            return resource;
        } else {
            throw new RuntimeException("FAIL!");
        }
    } catch (MalformedURLException e) {
        throw new RuntimeException("FAIL!");
    }
}

public void deleteAll() {
    FileSystemUtils.deleteRecursively(rootLocation.toFile());
}

public void init() {
    try {
        Files.createDirectory(rootLocation);
    } catch (IOException e) {
        throw new RuntimeException("Could not initialize storage!");
    }
}
}

2) ফাইল আপলোড এবং পেতে রেস্ট কন্ট্রোলার তৈরি করুন

@Controller
public class UploadController {

@Autowired
StorageService storageService;

List<String> files = new ArrayList<String>();

@PostMapping("/post")
public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
    String message = "";
    try {
        storageService.store(file);
        files.add(file.getOriginalFilename());

        message = "You successfully uploaded " + file.getOriginalFilename() + "!";
        return ResponseEntity.status(HttpStatus.OK).body(message);
    } catch (Exception e) {
        message = "FAIL to upload " + file.getOriginalFilename() + "!";
        return      ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
    }
}

@GetMapping("/getallfiles")
public ResponseEntity<List<String>> getListFiles(Model model) {
    List<String> fileNames = files
            .stream().map(fileName -> MvcUriComponentsBuilder
                    .fromMethodName(UploadController.class, "getFile", fileName).build().toString())
            .collect(Collectors.toList());

    return ResponseEntity.ok().body(fileNames);
}

@GetMapping("/files/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> getFile(@PathVariable String filename) {
    Resource file = storageService.loadFile(filename);
    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
            .body(file);
}

}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.