SpringMVC详解
@RequestMapping详解
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。这句话,太熟悉了。
一. RequestMapping路径详解
(1)首先springmvc.xml配置
(2)Controller 类
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/jsp")
public class RequestController {
public static final String SUCCESS="success";
@RequestMapping("/login1")
public void hello(){
System.out.println("hello world");
}
/*第一点
*1:@RequestMapping定义在类上,那就相当于根目录
*2:@RequestMapping定义在方法上,那就相当于相对于类定义处的URL。
* 上面代码在类定义处指定映射为"/jsp",在hello()方法处指定为"/login1"。
* 那么hello()方法的URL映射地址为:http://localhost:8080/ssm/jsp/login1
* ssm指的是你项目的名称
*/
/*第二点
* 1.@RequestMapping在类上定义不是必须的,如上如果我只在方法上定义@RequestMapping("/jsp/login1")
* 那么它同样能访问上面的URL映射地址。
* 2.@RequestMapping的默认属性为value,所以@RequestMapping(value="/login1")和@RequestMapping("/login1")是等价的。
*/
@RequestMapping("/login2")
public String getModel(){
System.out.println("hello world");
return SUCCESS;
}
/*第三点:需要返回界面
*1.这个return success;加上springMVC配置的路径
* 那么它返回的路径是:
* http://localhost:8080/ssm/WEB-INF/jsp/success.jsp
*/
@RequestMapping(value="/jsp/login3")
public ModelAndView paramBind(){
ModelAndView modelAndView = new ModelAndView();
//传到界面的数据
modelAndView.addObject("date", "nihao");
modelAndView.setViewName(SUCCESS);
return modelAndView;
}
/*第四点:返回界面同时带上数据
* 1.好多时候,我们要的不是跳转界面,而是能够把后台的数据传到前端去
* modelAndView.addObject放的就是你要传的数据
* modelAndView.setViewName返回路径名称
* 所以它的返回路径和上面一样
*/
/*第五点:void类型无返回值跳转
* 1.根据上面无返回值那么它最终会跳转到
* http://localhost:8080/ssm/WEB-INF/jsp/jsp/login1.jsp
* 原则:
* prefix+类路径(类级别的mapping注解)+方法路径(方法级别的mapping注解)+prefix
*/
}
二.RequestMapping参数详解
请求参数的作用是使得请求的映射更加精细。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明
value:定义处理方法的请求的 URL 地址。(重点)
method:定义处理方法的 http method 类型,如 GET、POST 等。(重点)
params: 定义请求的 URL 中必须包含的参数。或者不包含某些参数。(了解)
headers: 定义请求中 Request Headers 必须包含的参数。或者不包含某些参数。(了解)
下面也用个Controller 类来说明
1. Controller
@Controller
@RequestMapping("/hello")
public class TestController {
public static final String SUCCESSS="successs";
/**
* post动作请求的测试
*/
@RequestMapping(method=RequestMethod.POST,value="/login1")
public String testMethodPost(){
return SUCCESSS;
}
/**
* 测试url中带参数(未测试请求头信息)
*/
//url http://localhost:8080/ssm/hello/login2?username=zhangsan&password=123&sex=2
@RequestMapping(value="/login2",
params={"username","sex!=1","password=123"},
method=RequestMethod.GET)
public String testHeadersAndParams(){
return SUCCESSS;
}
/**
* PathVariable 映射 URL 绑定占位 ( 映射URL路径里面的变量)
*
* 用Integer会比int严谨
*/
//http://localhost:8080/ssm/hello/login3/5
@RequestMapping(value="/login3/{id}",method=RequestMethod.GET)
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("id:"+id);
return SUCCESSS;
}
// http://localhost:8080/ssm/hello/login4/str
@RequestMapping(value="/login4/{name}",method=RequestMethod.GET)
public String testPathVariable2(@PathVariable("name") String name){
System.out.println("name :"+name);
return SUCCESSS;
}
/**
* 如果在方发上@RequestMapping()没有任何参数,那它就代表类上的value请求地址
*
*/
// http://localhost:8080/ssm/hello.jsp
@RequestMapping()
public String test(){
return SUCCESSS;
}
}
有关RequestMapping就先讲这么多。
springMVC(1)---获取前段数据
首先说明,如果你学过Struts2,那么在学springMVC就会简单很多,我也不最基础的开始写了,我前篇文章搭建了个ssm框架,算是springmvc入门了。
链接:基于maven的ssm框架整合
一. 有哪些绑定数据的注解:
1.@RequestParam,绑定单个请求数据,可以是URL中的数据,表单提交的数据或上传的文件;
2.@PathVariable,绑定URL模板变量值;
3.@CookieValue,绑定Cookie数据;
4.@RequestHeader,绑定请求头数据;
5.@ModelAttribute,绑定数据到Model;
6.@SessionAttributes,绑定数据到Session;
7.@RequestBody,用来处理Content-Type不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;
8.@RequestPart,绑定“multipart/data”数据,并可以根据数据类型进项对象转换;
二.@RequestParam讲解
首先说明,项目的框架和架包我直接用的是smm框架整合的内容,我是在这个基础上进行操作,先看我jsp放置。
(1)先看Controller层
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ParamController {
/**
* GET请求
*/
@RequestMapping(value="/jsp/paramdate", method = {RequestMethod.GET})
public ModelAndView paramBind(){
ModelAndView modelAndView = new ModelAndView();
//因为我这边指定是post请求,所以不会走到这里,所以haha.jsp也没有写
modelAndView.setViewName("haha");
return modelAndView;
}
/**
* POST请求
*/
@RequestMapping(value="/jsp/paramdate", method = {RequestMethod.POST})
public ModelAndView paramBind(HttpServletRequest request, @RequestParam("urlParam") String urlParam, @RequestParam("formParam")
String formParam, @RequestParam("formFile") MultipartFile formFile){
//通过注解直接获得
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("urlParam", urlParam);
modelAndView.addObject("formParam", formParam);
modelAndView.addObject("formFileName", formFile.getOriginalFilename());
//如果不用注解获得数据,我们也可以手动获取
String urlParam1 = ServletRequestUtils.getStringParameter(request, "urlParam", null);
String formParam1 = ServletRequestUtils.getStringParameter(request, "formParam", null);
MultipartFile formFile1 = ((MultipartHttpServletRequest) request).getFile("formFile");
modelAndView.addObject("urlParam1", urlParam1);
modelAndView.addObject("formParam1", formParam1);
modelAndView.addObject("formFileName1", formFile1.getOriginalFilename());
//setViewName代表返回界面名称
modelAndView.setViewName("return");
return modelAndView;
}
}
(2)开始的start.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
界面
(3)返回return.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
注解获取数据:
${urlParam}
${formParam}
${formFileName}
手动获取数据:
${urlParam1}
${formParam1}
${formFileName1}
界面
通过这个小案例,我们通过注解和非注解的方式,把前段界面的值传到后端,在从后端传到前段。
思考:我们在实际开发中,在前段往后段传值的时候,后端一个一个获取值再放到Model实体中,还是太麻烦。别担心,我们不需要把数据绑定到一个个变量然后在对model赋值,只需要把model加入相应的action参数(这里不需要指定绑定数据的注解)Spring MVC会自动进行数据转换并绑定到model对象上,一切就是这么简单。
三.通过实体获取前端值
(1)建立User实体
public class User {
private String name;
private String password;
/*提供set和get方法,toString方法*/
}
(2)建立Controller类
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ssm.model.User;
@Controller
public class UsersController {
@RequestMapping("/jsp/loging")
public void getUser(HttpServletRequest request, Model model,User user){
User users=user;
System.out.println(users.getName()+"--"+users.getPassword());
}
}
(3)开始loging.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
用户名:
密 码:
界面 (密码123)
(4)最后我们在后台看我们打印的那条数据
已经成功,直接把属性注入到了user中。
springMVC(3)---利用pdf模板下载
在实际开发中,很多时候需要通过把数据库中的数据添加到pdf模板中,然后供客户下载,那我们该如何中呢?
本文主要内容是:用java在pdf模板中加入数据,图片
直接举例:
第一步,对pdf模板添加文本域
使用Adobe Acrobat Pro软件,选择表单,就可以添加文本域很简单。这里也可以设置字体大小,是否换行等
第二步、pom文件导入相关jar包
com.itextpdf
itextpdf
5.5.10
第三步,把pdf和照片素材放到项目中
这里我在resources下面新建了pdf文件夹,放到这里面
第四步、PdfController.java
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
@Controller
@RequestMapping("/jsp/exportpdf")
public class PdfController {
@RequestMapping
public String pdfexport(HttpServletResponse response) {
// 指定解析器
System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
String filename = "resume.pdf";
response.setContentType("application/pdf");
try {
//设置文件头:最后一个参数是设置下载文件名(这里我们叫:个人简历.pdf)
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("个人简历.pdf", "UTF-8"));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
OutputStream os = null;
PdfStamper ps = null;
PdfReader reader = null;
try {
os = response.getOutputStream(); // 生成的新文件路径 ,这里指页面
/**
* class.getResource("/") --> 返回class文件所在的顶级目录,一般为包名的顶级目录
* 在这个目录中src/main/java和src/main/resources和src/test/java都是属于顶级目录
* 这里pdf/就属于顶级目录下的子目录了
*
*/
// 2 读入pdf表单
reader = new PdfReader(PdfController.class.getResource("/pdf/") + "resume.pdf");
// 3 根据表单生成一个新的pdf
ps = new PdfStamper(reader, os);
// 4 获取pdf表单中所有字段
AcroFields form = ps.getAcroFields();
// 5给表单添加中文字体 这里采用系统字体。不设置的话,中文可能无法显示
BaseFont bf = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
form.addSubstitutionFont(bf);
// 6查询数据
Map data = new HashMap();
data.put("xh", "1021229");
data.put("xm", "徐小筱");
// 7遍历data 给pdf表单表格赋值
for (String key : data.keySet()) {
form.setFieldProperty(key, "textfont", bf, null);// 设置字体
form.setField(key, data.get(key).toString());
}
// 如果为false那么生成的PDF文件还能编辑,一定要设为true
ps.setFormFlattening(true);
//添加图片: 通过域名获取所在页和坐标,左下角为起点
int pageNo = form.getFieldPositions("zp").get(0).page;
Rectangle signRect = form.getFieldPositions("zp").get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
// 读图片
String imgpath = PdfController.class.getResource("/pdf/") + "zhaopian.jpg";
Image image = Image.getInstance(imgpath);
// 获取操作的页面
PdfContentByte under = ps.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 添加图片
image.setAbsolutePosition(x, y);
under.addImage(image);
System.out.println("===============PDF导出成功=============");
} catch (Exception e) {
System.out.println("===============PDF导出失败=============");
e.printStackTrace();
} finally {
try {
ps.close();
reader.close();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
第五步、jsp文件映射到Controller层
只要点击下载,文件就自动下载了
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
最终结果:完美!
springMVC(4)---生成excel文件并导出
在开发过程中,需要将数据库中的数据以excel表格的方式导出。
首先说明。我这里用的是Apache的POI项目,它是目前比较成熟的HSSF接口,用来处理Excel对象。其实POI不仅仅只能处理excel,它还可以处理word、PowerPoint、Visio、甚至Outlook。
一.首先介绍利用POI如何生成excel。
首先在生成Excel前,我们需要理解一下Excel文件的组织形式。在POI中,是这样理解的:一个Excel文件对应一个workbook,一个workerbook是有若干个sheet组成的。一个sheet有多个row,一个row一般存在多个cell。
对于上面的四个名词我们可以在下图理解:
对于生成Excel,POI提供了如下几个基本对象:
HSSFWorkbook excel 的文档对象
HSSFSheet excel 的表单
HSSFRow excel 的行
HSSFCell excel 的格子单元
从上面的图片和Excel的组织结构,我们就可以明白创建Excel的步骤。
1、生成文档对象HSSHWorkbook。
2、通过HSSFWorkbook生成表单HSSFSheet。
3、通过HSSFSheet生成行HSSFRow
4、通过HSSFRow生成单元格HSSFCell。
下面展示代码:
第一步、导入jar包
org.apache.poi poi-ooxml 3.9
第二步,创建Model对象
public class Person {
private String id;
private String name;
private String password;
private String age;
public Person(String id, String name, String password, String age) {
super();
this.id = id;
this.name = name;
this.password = password;
this.age = age;
}
//提供set和get方法
}
第三步.下载界面 exportexcel.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<script type="text/javascript">
function download(){
var url="download_excel?id=10&name=张三";
window.open(url);
}
</script>
第四步、ExcleController.java
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ssm.service.impl.ExcleImpl;
@Controller
public class ExcleController {
//这里直接new了
ExcleImpl excleImpl=new ExcleImpl();
@RequestMapping(value="/jsp/download_excel")
//获取url链接上的参数
public @ResponseBody String dowm(HttpServletResponse response,@RequestParam("id") String id,@RequestParam("name") String name){
response.setContentType("application/binary;charset=UTF-8");
try{
ServletOutputStream out=response.getOutputStream();
try {
//设置文件头:最后一个参数是设置下载文件名(这里我们叫:张三.pdf)
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(name+".xls", "UTF-8"));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
String[] titles = { "用户id", "用户姓名", "用户密码", "用户年龄" };
excleImpl.export(titles, out);
return "success";
} catch(Exception e){
e.printStackTrace();
return "导出信息失败";
}
}
}
第五步、ExcleImpl 报表导出实现层
import java.util.ArrayList;
import javax.servlet.ServletOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import com.ssm.model.Person;
public class ExcleImpl {
public void export(String[] titles, ServletOutputStream out) throws Exception{
try{
// 第一步,创建一个workbook,对应一个Excel文件
HSSFWorkbook workbook = new HSSFWorkbook();
// 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet hssfSheet = workbook.createSheet("sheet1");
// 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
HSSFRow row = hssfSheet.createRow(0);
// 第四步,创建单元格,并设置值表头 设置表头居中
HSSFCellStyle hssfCellStyle = workbook.createCellStyle();
//居中样式
hssfCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
HSSFCell hssfCell = null;
for (int i = 0; i < titles.length; i++) {
hssfCell = row.createCell(i);//列索引从0开始
hssfCell.setCellValue(titles[i]);//列名1
hssfCell.setCellStyle(hssfCellStyle);//列居中显示
}
// 第五步,写入实体数据
Person person1=new Person("1","张三","123","26");
Person person2=new Person("2","李四","123","18");
Person person3=new Person("3","王五","123","77");
Person person4=new Person("4","徐小筱","123","1");
//这里我把list当做数据库啦
ArrayList list=new ArrayList();
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
for (int i = 0; i < list.size(); i++) {
row = hssfSheet.createRow(i+1);
Person person = list.get(i);
// 第六步,创建单元格,并设置值
String id = null;
if(person.getId() != null){
id = person.getId();
}
row.createCell(0).setCellValue(id);
String name = "";
if(person.getName() != null){
name = person.getName();
}
row.createCell(1).setCellValue(name);
String password = "";
if(person.getPassword() != null){
password = person.getPassword();
}
row.createCell(2).setCellValue(password);
String age=null;
if(person.getAge() !=null){
age = person.getAge();
}
row.createCell(3).setCellValue(age);
}
// 第七步,将文件输出到客户端浏览器
try {
workbook.write(out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
throw new Exception("导出信息失败!");
}
}
}
第六步:最终效果,当我点击报表导出按钮
完美!
springMVC(5)---导入excel文件数据到数据库
上一篇文章写了从数据库导出数据到excel文件,这篇文章悄悄相反,写的是导入excel文件数据到数据库。上一篇链接:springMVC(4)---生成excel文件并导出
直接进入步骤讲解:
第一步、导入jar包
org.apache.poi poi-ooxml 3.9
第二步,创建Model对象
我没有把数据放到数据库中,而是导入到实体中,然后在后台打印
public class Family {
//家庭编号
private String jtbh;
//姓名
private String xm;
//行业
private String hy;
//备注
private String bz;
/*
* 提供set和get,toString方法
*/
}
第三步.导入excel界面 leadingexcel.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<script type="text/javascript" src="../js/jquery-1.7.1.js"></script>
<script type="text/javascript" src="../js/jquery.form.js"></script>
<script type="text/javascript">
/* ajax 方式上传文件操作 */
$(document).ready(function(){
$("#btn").click(function(){ if(checkData()){
$('#form1').ajaxSubmit({
url:'uploadExcel/ajax',
dataType: 'text',
success: resutlMsg,
error: errorMsg
});
function resutlMsg(msg){
alert(msg);
$("#upfile").val("");
}
function errorMsg(){
alert("导入excel出错!");
}
}
});
});
//JS校验form表单信息
function checkData(){
var fileDir = $("#upfile").val();
var suffix = fileDir.substr(fileDir.lastIndexOf("."));
if("" == fileDir){
alert("选择需要导入的Excel文件!");
return false;
}
if(".xls" != suffix && ".xlsx" != suffix ){
alert("选择Excel格式的文件导入!");
return false;
}
return true;
}
</script>
先讲下,我这src引用路径的时候发现,怎么也引用不到,找了好久才发现,我在springmvc中没有配置静态文件
springmvc.xml
第四步、LeadingExcelController.java
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.ssm.model.Family;
import com.ssm.service.impl.ImportExcelUtil;
@Controller
@RequestMapping("/jsp/uploadExcel")
public class LeadingExcelController {
@RequestMapping("/form")
public String form(HttpServletRequest request)throws Exception{
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
InputStream in =null;
List> listob = null;
MultipartFile file = multipartRequest.getFile("upfile");
if(file.isEmpty()){
throw new Exception("文件不存在!");
}
in = file.getInputStream();
listob = new ImportExcelUtil().getBankListByExcel(in,file.getOriginalFilename());
in.close();
//该处可调用service相应方法进行数据保存到数据库中,现只对数据输出
for (int i = 0; i < listob.size(); i++) {
List
第五步、ImportExcelUtil.java 报表导入实现层
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ImportExcelUtil {
private final static String excel2003L =".xls"; //2003- 版本的excel
private final static String excel2007U =".xlsx"; //2007+ 版本的excel
/**
* 描述:获取IO流中的数据,组装成List>对象
* @param in,fileName
* @return
* @throws IOException
*/
public List> getBankListByExcel(InputStream in,String fileName) throws Exception{
List> list = null;
//创建Excel工作薄
Workbook work = this.getWorkbook(in,fileName);
if(null == work){
throw new Exception("创建Excel工作薄为空!");
}
Sheet sheet = null;
Row row = null;
Cell cell = null;
list = new ArrayList>();
//遍历Excel中所有的sheet
for (int i = 0; i < work.getNumberOfSheets(); i++) {
sheet = work.getSheetAt(i);
if(sheet==null){continue;}
//遍历当前sheet中的所有行
for (int j = sheet.getFirstRowNum(); j < sheet.getLastRowNum(); j++) {
row = sheet.getRow(j);
if(row==null||row.getFirstCellNum()==j){continue;}
//遍历所有的列
List li = new ArrayList();
for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
cell = row.getCell(y);
li.add(this.getCellValue(cell));
}
list.add(li);
}
}
in.close();
return list;
}
/**
* 描述:根据文件后缀,自适应上传文件的版本
* @param inStr,fileName
* @return
* @throws Exception
*/
public Workbook getWorkbook(InputStream inStr,String fileName) throws Exception{
Workbook wb = null;
String fileType = fileName.substring(fileName.lastIndexOf("."));
if(excel2003L.equals(fileType)){
wb = new HSSFWorkbook(inStr); //2003-
}else if(excel2007U.equals(fileType)){
wb = new XSSFWorkbook(inStr); //2007+
}else{
throw new Exception("解析的文件格式有误!");
}
return wb;
}
/**
* 描述:对表格中数值进行格式化
* @param cell
* @return
*/
public Object getCellValue(Cell cell){
Object value = null;
DecimalFormat df = new DecimalFormat("0"); //格式化number String字符
SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd"); //日期格式化
DecimalFormat df2 = new DecimalFormat("0.00"); //格式化数字
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
value = cell.getRichStringCellValue().getString();
break;
case Cell.CELL_TYPE_NUMERIC:
if("General".equals(cell.getCellStyle().getDataFormatString())){
value = df.format(cell.getNumericCellValue());
}else if("m/d/yy".equals(cell.getCellStyle().getDataFormatString())){
value = sdf.format(cell.getDateCellValue());
}else{
value = df2.format(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
value = cell.getBooleanCellValue();
break;
case Cell.CELL_TYPE_BLANK:
value = "";
break;
default:
break;
}
return value;
}
}
第六步:最终效果,当我点击通过表单和ajax提交时
(1)先展示上传的xls文件内容
(2)最终控制台打出:
(3)通过ajax导入成功,前端也会提示
完美!
springMVC(6)---处理模型数据
之前一篇博客,写个怎么获取前段数据:springMVC(2)---获取前段数据,这篇文章写怎么从后端往前端传入数据。
模型数据类型
SpringMVC 提供了以下几种途径输出模型数据:
– ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加模型数据
– Map及Model:入参为org.springframework.ui.Model、org.springframework.ui.ModelMap 或 Java.uti.Map 时,处理方法返回时,Map中的数据会自动添加到模型中。
– @SessionAttributes: 将模型中的某个属性暂存到HttpSession 中,以便多个请求之间可以共享这个属性
– @ModelAttribute: 方法入参标注该注解后, 入参的对象就会放到数据模型中。
一.ModelAndView
目标方法的返回值可以是ModelAndView类型,其中可以包含视图和模型信息
springmvc会把ModelAndView的model中数据放在request域对象中
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
/**
* 目标方法的返回值可以是ModelAndView类型
* 其中可以包含视图和模型信息
* springmvc会把ModelAndView的model中数据放在request域对象中
* @return*/
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
String viewName=SUCCESS;
//添加模型视图
ModelAndView modelAndView=new ModelAndView(viewName);
//添加模型数据到ModelAndView中
modelAndView.addObject("time", new Date());
return modelAndView;
}
index.jsp
Test ModelAndView
success.jsp
Success Page
time:${requestScope.time}
二.Map 及 Model
入参为org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中
Controller类
@RequestMapping("/testMap")
public String testMap(Map map)
{
map.put("names", Arrays.asList("tom", "jerry", "mike"));
return "success";
index.jsp
Test Map
success.jsp
map: ${requestScope.names }
界面
三.@SessionAttributes
如果希望在多个请求之间共用某个模型属性数据,则可以在控制器类标注一个 @SessionAttributes,SpringMVC 会将模型中对应的属性暂存到 HTTPSession 中。
@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中。
1. @SessionAttributes(types=User.class)会将隐含模型中所有类型为 User 的属性添加到会话中
2. @SessionAttributes(value={"user1", "user2"})将名为 user1 和 user2 的模型属性添加到会话中
3. @SessionAttributes(types={"User.class", "Dept.class"})将模型中所有类型为 User 及 Dept 的属性添加到会话中
4. @SessionAtributes(value={"user1", "user2"}, types={Dept.class})将名为 user1 和 user2 的模型属性添加到会话中,同时将所有类型为 Dept 的模型属性添加到会话中
controller类
//SessionAttributes只能放在类上,不能在方法上
@SessionAttributes(value={"user"}, types={String.class})
@RequestMapping("/springmvc")
@Controller
public class SessionController
{
private static final String SUCCESS = "success";
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Map map)
{
User user = new User("Jack", "123");
map.put("user", user);
map.put("msg", "hello");
return SUCCESS;
}
}
index.jsp
Test SessionAttributes
success.jsp
request user: ${requestScope.user }
request msg: ${requestScope.msg }
session user: ${sessionScope.user }
session msg: ${sessionScope.msg }
最终request和session都有相应值,由此我们可以得出:
被 @SessionAttributes 注解修饰后,模型属性不仅存在于请求域还存在于会话域。除了可以通过value属性值指定需要放到会话中的属性外,还可以根据types属性值指定哪些类型的模型属性需要放到会话中。
四.@ModelAttribute
@ModelAttribute注解只支持一个属性value,类型是为String,代表绑定的属性名称。
@ModelAttribute会优先于@RequestMapping执行,也会在Controller中每个方法执行前被执行,所以当一个Controller中有映射到多个Url时,需要谨慎使用
(1)先讲下基本理解,网上讲的无非就那么几种:
@ModelAttribute
public void myModel3(Model model) {
model.addAttribute("name", "SHANHY");
model.addAttribute("age", "28");
}
/**
* 这个相当于 model.addAttribute("name", name);
*/
@ModelAttribute("name")
public String userModelfirst(@RequestParam("name") String name){
return name;
}
/**
* 这个相当于 model.addAttribute("string", name);
* 因为你自己没有设置model的key值,所以它会默认value的类型第一个字母小写作为key值
* 如果你是User对象,那它会默认key值为"user",这个在实际开发中并不适用
* 因为太局限了,我们很难接受 key 为 string、int、user 等等这样的。
*/
@ModelAttribute
public String myModel1(@RequestParam(required = false) String name) {
return name;
}
(2)RequestMapping方法中取ModelAttribute方法中的值
modelattr.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
ModelAttrController类
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping(value="/modelattr")
public class ModelAttrController {
@ModelAttribute
public void Model1(Model model) {
model.addAttribute("name", "张三");
model.addAttribute("pwd", "1234");
}
/**
* test1方法中,有两个值是通过Model1方法中放入的
* 有两个值是通过前端获取的我们看后台打印结果
*/
@RequestMapping(value="/test1")
public String test1(
@ModelAttribute("name") String str2,
@ModelAttribute("pwd") String str3,
@RequestParam("name") String name,
@RequestParam("pwd") String pwd) {
System.out.println("name="+str2+",pwd="+str3);
System.out.println("name="+name+",pwd="+pwd);
return null;
}
}
后台打印结果:
(3)有关更新,具体看案例
modelPerson.jsp
ModelAttrController类
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.ssm.model.Person;
@Controller
@RequestMapping(value="/modelattr")
public class ModelAttrController {
/**
*1: 因为password我在界面上是没有输入的,所以我通过id去数据库找到这条数据,就能获得它的password
*2:Person领域对象就id name password age 四个属性都是String形
*/
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false) String id,
Map map){
if(id != null){
//模拟从数据库中获取对象
Person person = new Person("1", "lisi", "123456", "24");
System.out.println("从数据库中获取一个对象: " + person);
map.put("person", person);
}
}
@RequestMapping(value="/person", method=RequestMethod.POST)
public String testModelAttribute(Person person){
System.out.println("修改: " + person);
return null;
}
/*
* 总结几点:
* 1:map.put("person", person);中的key值,一定要和Person person中的形参一致,否则报错
* 2:如果去掉@ModelAttribute注解和getUser方法,直接testModelAttribute(Person person)会报错
* java.lang.NoSuchMethodException: com.ssm.model.Person.()
* 3:最后修改的那个person其实就是从数据库中和前端界面传来的集合体,就是说如果前端有值那就覆盖数据库中对于
* 属性的值,如果前段没有值那就还是用数据库中属性的值
*/
}
后台打印结果
(4)@ModelAttribute和@RequestMapping同时注释的有返回值的方法
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping(value="/modelattr")
public class ModelAttrController {
@ModelAttribute(value="username")
@RequestMapping("/person")
public String login(@RequestParam("name") String name){
return name;
}
/**
* 这种情况比较有意思:以前return name;都是作为返回路径
* 现在它变成了value值
* model.addAttribute("username", name);
* 那它的映射还是@RequestMapping中的value值这里指:modelattr/person
* 我之前路径为:http://localhost:8080/ssm/modelattr/person
* 那么返回路径为:http://localhost:8080/ssm/WEB-INF/jsp/modelattr/person.jsp
*/
}
先看WEB-INF/jsp/modelattr/person.jsp
内容
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Person返回成功