파일 첨부 할때 사용 되는 MimeMessageHelper.addAttachment(String attachmentFilename, InputStreamSource inputStreamSource) 메소드에 MultipartHttpRequest 에서 직접 InputStream 객체를 연결 하면 문제가 발생 한다.


Buffer 에 파일을 임시로 담아 놓고, InputStream 으로 변환하면 해결 된다.


for (MultipartFile uploadFile : uploadFiles) {
    String originalFilename = uploadFile.getOriginalFilename();

    logger.debug("addAttachment: {}", originalFilename);
    logger.debug("addAttachment size: {}", uploadFile.getSize());

    mimeMessageHelper.addAttachment(MimeUtility.encodeText(originalFilename), new ByteArrayResource(IOUtils.toByteArray(uploadFile.getInputStream())));
}


IOUtils 이 없다면, pom.xml 에 추가 하자.


<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>1.4</version>
</dependency>

참고 사이트


Java Mail을 기반으로 하여 작성된 Spring Mail 라이브러리가 있다. 적용 해 보자.


pom.xml에 라이브러리를 추가 한다.


<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>3.0.5.RELEASE</version>
</dependency>


applicationContext.xml 에 Mail Sender Class 설정을 추가 하자. 필요에 따라 Properties 에서 SpringExpressionLanguage (SpEL) 문법을 사용해도 된다.


<util:properties id="config" location="classpath:config/config.properties" />

<!-- Spring mail configuration -->
<beans:bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
     <beans:property name="host" value="#{config['mail.host']}" />
     <beans:property name="port" value="#{T(java.lang.Integer).parseInt(config['mail.port'])}" />
     <beans:property name="username" value="#{config['mail.username']}" />
     <beans:property name="password" value="#{config['mail.password']}" />
     <beans:property name="defaultEncoding" value="#{config['mail.defaultEncoding']}" />

     <beans:property name="javaMailProperties">
        <beans:props>
            <beans:prop key="mail.transport.protocol">#{config['mail.protocol']}</beans:prop>
            <beans:prop key="mail.smtp.auth">true</beans:prop>
            <beans:prop key="mail.smtp.starttls.enable">false</beans:prop>
        </beans:props>
     </beans:property>
</beans:bean>


메일을 보낼 수 있는 Interface 를 작성 한다. 제네릭 문법으로 report 를 받는 것은 원하는 타입에 맞게 메일 내용을 작성 할 수 있게 하기 위해서 이다.


public interface Publisher {
    public <T> boolean publish(T report);
}


실제 메일 발송에 대한 구현 클래스 이다.


@Service("EmailPublisherService")
public class EmailPublisherService implements Publisher {

    private static final Logger logger = LoggerFactory.getLogger(EmailPublisherService.class);

    @Autowired
    private JavaMailSender javaMailSender;

    @Override
    public <T> boolean publish(T report) {
        logger.debug("Sending report by email...");
        boolean retVal = false;
        try {
            final String emailTo = "to@test.co.kr";
            final String emailFrom = "from@test.co.kr";
            final String subject = "test subject";
            final String message = (String) report;

            javaMailSender.send(new MimeMessagePreparator() {

                @Override
                public void prepare(MimeMessage paramMimeMessage) throws Exception {
                    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(paramMimeMessage, true, "UTF-8");

                    mimeMessageHelper.setTo(emailTo);
                    mimeMessageHelper.setFrom(emailFrom);
                    mimeMessageHelper.setSubject(subject);
                    mimeMessageHelper.setText(message);

                    final File file = new File("test filename");

                    mimeMessageHelper.addAttachment(MimeUtility.encodeText("filename"), new InputStreamSource() {

                        @Override
                        public InputStream getInputStream() throws IOException {
                            // TODO Auto-generated method stub
                            return new FileInputStream(file);
                        }
                    });

                };
            });

            retVal = true;
        } catch (Exception e) {
            logger.error("Can't send email... " + e.getMessage(), e);
        }
        return retVal;
    }
}


메일에 첨부 파일이 있는 경우 new MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, String encoding) 중 multipart 값을 true 로 변경 하고, MimeMessageHelper.addAttachment(attachmentFilename, inputStreamSource) 메소드를 사용 하자. 단 파일 명을 MimeUtility.encodeText(String text) 하지 않으면, 한글이 께져서 발송 된다.


@Controller
@RequestMapping(value="/mail")
public class SampleController {

    @Resource(name="EmailPublisherService")
    private EmailPublisherService emailPublisherService;

    @RequestMapping(value="/send")
    public @ResponseBody String send() throws Exception {
        try {
            emailPublisherService.publish("text message...");
            return "Success";
        } catch (Exception e) {
            throw e;
        }
    }
}


Controller 에 작성한 EmailPublisherService 를 Dependency Injection(DI) 하여 메일을 보내 보자.


참고 사이트


+ Recent posts