小结SpringMVC(二)

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/masterSpringMVC.git


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值