小结SpringMVC(二)
2016-06-05 07:26
573 查看
1.整合视图
到目前为止,我们的基本功能已经全部实现了,但是视图的页面过于分散了,我们需要将uploadPage的页面整合到profilePage的页面。整合后的profilePage.html如下:<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="layout/default"> <head lang="en"> <title>Your profile</title> </head> <body> <div class="row" layout:fragment="content"> <h2 class="indigo-text center" th:text="#{profile.title}">Personal info</h2> <div class="row"> <div class="col m8 s12 offset-m2"> <img th:src="@{/uploadedPicture}" width="100" height="100"/> </div> <div class="col s12 center red-text" th:text="${error}" th:if="${error}"> Error during upload </div> <form th:action="@{/profile}" method="post" enctype="multipart/form-data" class="col m8 s12 offset-m2"> <div class="input-field col s6"> <input type="file" id="file" name="file"/> </div> <div class="col s6 center"> <button class="btn indigo waves-effect waves-light" type="submit" name="upload" th:text="#{upload}"> Upload <i class="mdi-content-send right"></i> </button> </div> </form> </div> <form th:action="@{/profile}" th:object="${profileForm}" method="post" class="col m8 s12 offset-m2"> <div class="row"> <div class="input-field col s6"> <input th:field="${profileForm.twitterHandle}" id="twitterHandle" type="text" required="required" th:errorclass="invalid"/> <!--lable是在输入信息框中,用于信息提示,只要鼠标点击,它就上移(以下都一样)。--> <label for="twitterHandle" th:text="#{twitter.handle}">Twitter handle</label> <div th:errors="*{twitterHandle}" class="red-text">Error</div> </div> <div class="input-field col s6"> <input th:field="${profileForm.email}" id="email" type="email" required="required" th:errorclass="invalid"/> <label for="email" th:text="#{email}">Email</label> <div th:errors="*{email}" class="red-text">Error</div> </div> </div> <!--th:placeholder="${}"或th:placeholder="#{}"是提示输入的格式--> <div class="row"> <div class="input-field col s6"> <input th:field="${profileForm.birthDate}" id="birthDate" type="text" required="required" th:errorclass="invalid" th:placeholder="${dateFormat}"/> <label for="birthDate" th:text="#{birthdate}" th:placeholder="${dateFormat}">Birth Date</label> <div th:errors="*{birthDate}" class="red-text">Error</div> </div> </div> <!--添加Add Taste的功能--> <fieldset class="row"> <legend th:text="#{tastes.legend}">What do you like?</legend> <button class="btn teal" type="submit" name="addTaste" th:text="#{add.taste}">Add taste <i class="mdi-content-add left"></i> </button> <div th:errors="*{tastes}" class="red-text">Error</div> <div class="row" th:each="row,rowStat : *{tastes}"> <!--rowStat是输入的信息,rowStat.index对应索引的信息--> <div class="col s6"> <input type="text" required="required" th:field="*{tastes[__${rowStat.index}__]}" th:placeholder="#{taste.placeholder}"/> </div> <div class="col s6"> <button class="btn red" type="submit" name="removeTaste" th:value="${rowStat.index}" th:text="#{remove}">Remove <i class="mdi-action-delete right waves-effect"></i> </button> </div> </div> </fieldset> <div class="row s12 center"> <button class="btn indio waves-effect waves-light" type="submit" name="save" th:text="#{submit}"> <i class="mdi-content-send right"></i> </button> </div> </form> </div> <!--只有提交submit的按键时才会提交,其它的情况是添加Teste 有了bug--> <script layout:fragment="script"> $('button').bind('click', function(e) { if (e.currentTarget.name === 'save') { $(e.currentTarget.form).removeAttr('novalidate'); } else { <!--添加无作用的标签novalidate--> $(e.currentTarget.form).attr('novalidate', 'novalidate'); } }); </script> </body> </html>
2.修改控制层
首先修改UserProfileSession类:package masterSpringMVC.profile; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Component; import java.io.IOException; import java.io.Serializable; import java.net.URL; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; /** * 保存登录用户的信息 * Created by OwenWilliam on 2016/5/19. */ @Component @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public class UserProfileSession implements Serializable { private String twitterHandle; private String email; private LocalDate birthDate; private List<String> tastes = new ArrayList<>(); private URL picturePath; //保存用户基本信息 public void saveForm(ProfileForm profileForm) { this.twitterHandle = profileForm.getTwitterHandle(); this.birthDate = profileForm.getBirthDate(); this.email = profileForm.getEmail(); this.tastes = profileForm.getTastes(); } public ProfileForm toForm() { ProfileForm profileForm = new ProfileForm(); profileForm.setTwitterHandle(twitterHandle); profileForm.setEmail(email); profileForm.setBirthDate(birthDate); profileForm.setTastes(tastes); return profileForm; } public void setPicturePath(Resource picturePath) throws IOException { this.picturePath = picturePath.getURL(); } public Resource getPicturePath() { return picturePath == null ? null : new UrlResource(picturePath); } public List<String> getTastes() { return tastes; } }
其次修改PictureUploadController类:
package masterSpringMVC.profile; import masterSpringMVC.config.PictureUploadProperties; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.util.WebUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Locale; /** * 文件上传刷新处理逻辑 * Created by OwenWilliam on 2016/5/17. */ @Controller @SessionAttributes("picturePath") public class PictureUploadController { private final Resource picturesDir; private final Resource anonymousPicture; private final MessageSource messageSource; private final UserProfileSession userProfileSession; /** * 自动获取picturesDir和annonymouspicture * @param uploadProperties */ @Autowired public PictureUploadController(PictureUploadProperties uploadProperties, MessageSource messageSource, UserProfileSession userProfileSession) { picturesDir = uploadProperties.getUploadPath(); anonymousPicture = uploadProperties.getAnonymousPicture(); this.messageSource = messageSource; this.userProfileSession = userProfileSession; } /* @RequestMapping("upload") public String uploadPage() { return "profile/uploadPage"; } */ /** * 上传图片 * @param file * @param redirectAttributes * @return * @throws IOException */ @RequestMapping(value = "/profile", params = {"upload"}, method = RequestMethod.POST) public String onUpload(@RequestParam MultipartFile file, RedirectAttributes redirectAttributes) throws IOException { // throw new IOException("Some Message"); if (file.isEmpty() || !isImage(file)) { redirectAttributes.addFlashAttribute("error", "Incorrect file.Please upload a picture."); return "redirect:/profile"; } Resource picturePath = copyFileToPictures(file); userProfileSession.setPicturePath(picturePath); //文件的路径放到session中 // model.addAttribute("picturePath", picturePath); return "redirect:profile"; } /** * 图片输出到对应文件夹 * @param file * @return * @throws IOException */ private Resource copyFileToPictures(MultipartFile file) throws IOException { //后缀名(如:.jpg) String fileExtension = getFileExtension(file.getOriginalFilename()); //路径+文件名(无后缀) File tempFile = File.createTempFile("pic",fileExtension, picturesDir.getFile()); try (InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(tempFile)) { //to write an input stream to an output stream IOUtils.copy(in, out); } return new FileSystemResource(tempFile); } /** * 刷新显示图片 * @param response * @throws IOException */ @RequestMapping(value = "/uploadedPicture") public void getUploadedPicture(HttpServletResponse response) throws IOException { Resource picturePath = userProfileSession.getPicturePath(); if (picturePath == null) { picturePath = anonymousPicture; } response.setHeader("Content-Type", URLConnection.guessContentTypeFromName(picturePath.toString())); // Path path = Paths.get(picturePath.getURI()); // Files.copy(path, response.getOutputStream()); IOUtils.copy(picturePath.getInputStream(), response.getOutputStream()); } /** * 默认的图上路径 * @return */ @ModelAttribute("picturePath") public Resource picturePath() { return anonymousPicture; } /** * 是否是图片 * @param file * @return */ private boolean isImage(MultipartFile file) { return file.getContentType().startsWith("image"); } /** * 获取后缀:如.jpg * @param name * @return */ private static String getFileExtension(String name) { return name.substring(name.lastIndexOf(".")); } @ExceptionHandler(IOException.class) public ModelAndView handleIOException(Locale locale) { ModelAndView modelAndView = new ModelAndView("profile/profilePage"); // modelAndView.addObject("error", exception.getMessage()); modelAndView.addObject("error",messageSource.getMessage("upload.io.exception", null, locale)); modelAndView.addObject("profileForm", userProfileSession.toForm()); return modelAndView; } @RequestMapping("uploadError") public ModelAndView onUploadError(Locale locale) { ModelAndView modelAndView = new ModelAndView("profile/profilePage"); // modelAndView.addObject("error", request.getAttribute(WebUtils.ERROR_MESSAGE_ATTRIBUTE)); modelAndView.addObject("error", messageSource.getMessage("upload.file.too.big", null, locale)); modelAndView.addObject("profileForm", userProfileSession.toForm()); return modelAndView; } }
3.总结
整合后,运行程序,你将会看到下面的页面。代码的结构:
源码下载:git@github.com:owenwilliam/masterSpringMVC4_assemble.git
相关文章推荐
- SpringMVC显示上传文件
- SpringMVC路径配置
- SpringMVC文件上传(三)异常栈处理
- SpringMVC文件上传(二)指定文件
- SpringMVC文件上传(一)
- 小结SpringMVC(一)
- SpringMVC实现list表单(六)
- SpringMVC国际化(i18n)(五)
- SpringMVC深入信息提示(四)
- SpringMVC错误提示(三)
- SpringMVC日期处理(二)
- SpringMVC创建用户信息(一)
- 使用Spring框架对接Twitter(二)
- Eclipse wtp project dependent project facets问题
- 配置log4j日志动态加载(不重启服务)
- springmvc开发问题汇总(环境搭建)
- 10040---Java IO --缓冲流
- SpringMvc入门五----文件上传
- 【代码笔记】Java深入学习——实现客户端发送文件到服务器的文件传输
- 编译 openJDK source code