Spring MVC中分逻辑视图和非逻辑视图:
- 逻辑视图是需要视图解析器(ViewResolver)进行进一步定位的。例如,Spring MVC之所以可以根据返回的字符串,能找到对应的JSP,就是因为使用了逻辑视图,经由视图解析器的定位后,才能找到视图将数据模型进行渲染展示给用户查看
- 非逻辑视图不需要定位视图的位置,它只需要将数据模型渲染出来即可。实际工作中视图解析器 InternalResourceViewResolver 比较常用
视图设计
除了JSON和JSP视图外,还有其它类型的视图,如果Excel、PDF等。它们都会实现SpringMVC定义的视图接口View
public interface View {
// 响应状态属性
String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";
// 路径变量名称
String PATH_VARIABLES = View.class.getName() + ".pathVariables";
// 选择内容类型
String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType";
//类型
@Nullable
default String getContentType() {
return null;
}
// 渲染方法
void render(@Nullable Map<String, ?> var1, HttpServletRequest var2, HttpServletResponse var3) throws Exception;
}
- getContentType 方法是获取HTTP响应类型,它可以返回的类型是文本、JSON数据集或者文件等。
- render 方法是将数据模型渲染到视图,这是视图的核心方法
- model是数据模型,实际就是从控制器返回的数据模型,这样 render方法将它渲染
SpringMVC 所提供的视图接口和类:
excel文件上传
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("file")
public class FileController {
@PostMapping("/upload/request")
@ResponseBody
public Map<String, Object> uploadRequest(HttpServletRequest request) {
boolean flag = false;
MultipartHttpServletRequest mreq = null;
if (request instanceof MultipartHttpServletRequest) {
mreq = (MultipartHttpServletRequest) request;
} else {
return dealResultMap(false, "上传失败");
}
MultipartFile mf = mreq.getFile("file");
String fileName = mf.getOriginalFilename();
File file = new File(fileName);
try {
mf.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
return dealResultMap(false, "上传失败");
}
return dealResultMap(true, "上传成功");
}
@PostMapping("/upload/multipart")
@ResponseBody
public Map<String, Object> uploadMultipartFile(MultipartFile file) {
String fileName = file.getOriginalFilename();
File dest = new File(fileName);
try {
file.transferTo(dest);
} catch (IOException e) {
e.printStackTrace();
return dealResultMap(false, "上传失败");
}
return dealResultMap(true, "上传成功");
}
@PostMapping("/upload/part")
@ResponseBody
public Map<String, Object> uploadPart(Part file) {
String fileName = file.getSubmittedFileName();
try {
file.write(fileName);
} catch (IOException e) {
e.printStackTrace();
return dealResultMap(false, "上传失败");
}
return dealResultMap(true, "上传成功");
}
public Map<String , Object> dealResultMap(boolean success, String msg) {
Map<String, Object> result = new HashMap<>();
result.put("success", success);
result.put("msg", msg);
return result;
}
}
调用控制器之前,DispatcherServlet会将其转换为MultipartHttpServletRequest对象,然后再获取 MultipartFile对象,接着使用MultipartFile对象获取到上传的文件名,而通过它的transferTo方法上传文件,从而进行操作。 uploadPart 方法是使用Servlet API,可以使用其write方法直接写入文件。