【java框架】SpringMVC(3)--SpringMVC控制器常用业务操作
1. springmvc控制器业务操作
在springmvc第二节中我们了解到mvc控制器处理页面url请求返回响应视图,除了这些操作外,控制器还需要处理更重要的业务,如:接收前台页面传递的参数、绑定数据到页面、返回json数据、文件上传、文件下载等业务操作。
1.1.参数接收
1.1.1. 配置请求编码过滤器
springmvc框架本身没有处理请求编码,在前台参数接收post请求的时候,可能会出现编码乱码的问题,而spring框架为我们提供了一个请求编码过滤器,我们只需要在web.xml中配置一个请求编码过滤器即可:
web.xml中配置utf-8编码如下:
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置post请求编码乱码处理过滤器--> <filter> <filter-name>characterencodingfilter</filter-name> <filter-class>org.springframework.web.filter.characterencodingfilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterencodingfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
1.1.2. 参数接收方式
get接收方式:
① 使用方法的形参接收:注意形参要和请求参数一致;
@controller @requestmapping(value = "/paramcontroller", method = requestmethod.get) public class paramreccotroller { /** * 参数接收方式一:使用形参接收,前台get请求传入的参数名和方法接收的参数名保持一致 * @param username * @param age */ @requestmapping("/insert") public void insert(string username, integer age){ system.out.println(username); system.out.println(age); } }
前台get参数传递方式:
http://localhost:8080/paramcontroller/insert?username=”青海”&age=21
获取到的参数信息:
② 如果形参名称和前台传入的参数名不一致,需要使用@requestparam(value=”前台参数名”)进行映射对应;
@controller @requestmapping(value = "/paramcontroller", method = requestmethod.get) public class paramreccotroller { /** * 参数接收方式二:前台get传递的参数url与方法形参某个参数不一致,需要使用@@requestparam(value = "前台参数名") * @param username * @param age */ @requestmapping("/insert") public void insert(@requestparam(value = "name") string username, integer age){ system.out.println(username); system.out.println(age); } }
前台get参数传递方式:
http://localhost:8080/paramcontroller/insert?name=”青海”&age=21
获取到的参数信息:
③ 直接使用一个domain对象接收前台参数,会根据domain中的属性来进行匹配装值;
@controller @requestmapping(value = "/paramcontroller", method = requestmethod.get) public class paramreccotroller { /** * 参数接收方式三:直接使用一个domain对象来接收前台参数,每个前台参数必须和user里面的属性名保持一致(前台参数直接映射属性), * 不然无法获取对应的参数值,而且必须保证user内有一个无参数的构造器 * @param user */ @requestmapping("/insert") public void insert(user user){ system.out.println(user); } }
对应domain中的user类:
public class user { private string username; private integer age; private string password; public user() { } public user(string username, integer age, string password) { this.username = username; this.age = age; this.password = password; } public string getusername() { return username; } public void setusername(string username) { this.username = username; } public integer getage() { return age; } public void setage(integer age) { this.age = age; } public string getpassword() { return password; } public void setpassword(string password) { this.password = password; } @override public string tostring() { return "user{" + "username='" + username + '\'' + ", age=" + age + ", password='" + password + '\'' + '}'; } }
前台get参数传递方式:
http://localhost:8080/paramcontroller/insert?username=”青海”&age=21&password= 3454
获取到的参数信息:
④ 使用原始的httpservletrequest来获取请求参数信息;
@controller @requestmapping(value = "/paramcontroller", method = requestmethod.get) public class paramreccotroller { /** * 参数接收方式四:直接使用httpservletrequest获取 * @param request */ @requestmapping("/insert") public void insert(httpservletrequest request){ string username = request.getparameter("username"); integer age = integer.valueof(request.getparameter("age")); string pwd = request.getparameter("pwd"); system.out.println(username); system.out.println(age); system.out.println(pwd); } }
前台get参数传递方式:
http://localhost:8080/paramcontroller/insert?username=”青海”&age=21&pwd= 3454
获取到的参数信息:
⑤ restful风格请求参数传递:直接在映射地址上使用{id}占位符,id表示传递的参数名,方法接收时对方法的形参使用@pathvariable(“id”),这里面的id应该和映射地址上的id名称保持一致;
@controller @requestmapping(value = "/paramcontroller", method = requestmethod.get) public class paramreccotroller { /** * 参数接收方式四:前台请求地址中包含id参数信息,使用restful风格映射对应相同的提取参数 * 注意:前台参数名称必须与restful风格的参数一一对应,名称一致 * @param idval */ @requestmapping("/insert/{id}") public void getuserbyid(@pathvariable(value = "id") integer idval){ system.out.println(idval); } }
前台get参数传递方式:
http://localhost:8080/paramcontroller/insert/5
获取到的参数信息:
1.2.数据传递
简单地说,就是使用springmvc中controller向前台页面传递数据。使用controller进行数据传递的方式主要有四种传递方式:
① 通过modelandview对象传递
@controller @requestmapping("/datacontroller") public class datatranscontroller { /** * 页面展示返回数据方式一:通过modelandview对象传递 * setviewname:返回一个结果视图 * addobject(name, value):可以通过name到对应的显示页面上去取数据,value表示显示的数据, * 也可以传递对象来取值 * @return */ @requestmapping("/getdata") public modelandview getdatares(){ modelandview modelandview = new modelandview(); modelandview.addobject("msg", "随便写一个msg信息"); modelandview.setviewname("/web-inf/views/dataview.jsp"); user user = new user("青海", 21, "2332"); modelandview.addobject("user", user); return modelandview; } }
对应jsp页面取值:
<body> ${msg}<br/> ${user}<br/> ${user.username}<br/> ${user.age}<br/> ${user.password}<br/> </body>
对应页面展示数据信息如下:
② 通过model对象进行数据传递;
@controller @requestmapping("/datacontroller") public class datatranscontroller { /** * 页面展示返回数据方式二:通过model对象传递 * return:返回一个结果视图 * addobject(name, value):可以通过name到对应的显示页面上去取数据,value表示显示的数据, * 也可以传递对象来取值 * @return */ @requestmapping("/getmodel") public string getmodelres(model model){ model.addattribute("msg", "model对象的信息"); user user = new user("青海", 21, "2332"); model.addattribute("user", user); return "/web-inf/views/modeldataview.jsp"; } }
对应jsp页面取值:
${msg}<br/> ${user}<br/> ${user.username}<br/> ${user.age}<br/> ${user.password}<br/>
对应页面展示数据信息如下:
③ 通过httpservletrequest对象进行数据传递;
这种方式与model对象传递方式类似,就是把参数换成httpservletrequest对象,调用request.setattribute(“msg”, 传递信息或者对象信息),这里就不再详细说明;
1.3.springmvc返回json数据
1.3.1. 实现方式
springmvc返回json数据格式需要导入jackson的jar包,jackson是解析json和xml的一个框架,简单易用,性能较高。
在项目中我们需要导入jackson json的工具包,如下:
jackson-annotations-2.5.0.jar
jackson-core-2.5.0.jar
jackson-databind-2.5.0.jar
对应controller实现方式:
@controller @requestmapping("/jsoncontroller") public class jsondemocontroller { @requestmapping("/getjson") //加上@responsebody注解,返回值是通过json流的方式输出,springmvc获取返回值,把对象自动转换为json //然后通过response.getwriter().print(jsonstring)输出在前台页面 @responsebody public user getjsonuserdata(){ user user = new user("青海", 21, "2332"); return user; } }
前台页面进行数据访问,访问地址:http://localhost:8080/jsoncontroller/getjson
同样可以返回一个json集合,对应实现如下:
@controller @requestmapping("/jsoncontroller") public class jsondemocontroller { @requestmapping("/getjsonlist") @responsebody public list<user> getjsonuserlstdata(){ user user1 = new user("青海", 21, "2332"); user user2 = new user("俊杰", 23, "3306"); list<user> userlist = new arraylist<>(); userlist.add(user1); userlist.add(user2); return userlist; } }
前台页面进行数据访问,访问地址:http://localhost:8080/jsoncontroller/getjsonlist
1.3.2 日期型数据格式化
在处理日期date类型的数据,如果后台不进行处理,那么默认返回的是时间戳的json日期格式:比如"birthday":1584261823034,此时需要在domain的日期get属性方法上加上@jsonformat(pattern="yyyy-mm-dd hh:mm:ss",timezone="gmt+8")
/** * 如果不加jsonformat,默认返回的日期格式是时间戳:比如"birthday":1584261823034 * 需要在日期属性date的getxxx()方法上加上自定义的日期格式@jsonformat注解 * @return */ @jsonformat(pattern="yyyy-mm-dd hh:mm:ss",timezone="gmt+8") public date getbirthday() { return birthday; }
同理,在前台向后台传入字符串类型的date数据时,需要在domain的日期set属性方法上加上@datetimeformat(pattern="yyyy-mm-dd hh:mm:ss"),后台才能接收到对应的date参数并转换为日期数据到后台
/** * 前台get方式brithday以字符形式传递,需要加上@datetimeformat注解, * 才能向后台传递date类型数据 * @param birthday */ @datetimeformat(pattern="yyyy-mm-dd hh:mm:ss") public void setbirthday(date birthday) { this.birthday = birthday; }
1.4.springmvc文件上传
springmvc自己没有实现文件上传,需要使用apache.commons.fileupload,需要导入文件上传相关的包:
com.springsource.org.apache.commons.fileupload-1.2.0.jar
com.springsource.org.apache.commons.io-1.4.0.jar
创建fileuploadcontroller:
@controller @requestmapping public class fileuploadcontroller { //通过get请求,返回一个文件上传的jsp页面--结果视图 @requestmapping(value = "/upload", method = requestmethod.get) public string uploadfileget(){ return "/web-inf/views/upload.jsp"; } //文件上传的实现方法 @requestmapping(value = "/upload", method = requestmethod.post) public string uploadfilepost(string name, multipartfile imge, httpservletrequest request) throws ioexception { //获取上传文件的原始文件名 string orifilename = imge.getoriginalfilename(); //获取文件名的后缀 string suffix = filenameutils.getextension(orifilename); //产生一个随机的文件名 string uuidname = uuid.randomuuid().tostring(); string filename = uuidname + "." +suffix; //获取文件的保存路径 string filedir = request.getservletcontext().getrealpath("/upload"); //使用file流来写入文件 file file = new file(filedir, filename); //文件夹不存在,就创建一个保存路径 if(!file.getparentfile().exists()){ file.getparentfile().mkdirs(); } //io流的拷贝 ioutils.copy(imge.getinputstream(), new fileoutputstream(file)); return "/web-inf/views/upload.jsp"; } }
准备jsp上传页面:
<%@ page contenttype="text/html;charset=utf-8" language="java" %> <html> <head> <title>文件上传页面</title> </head> <body> <!—文件上传:必须写:enctype="multipart/form-data"—> <form action="/upload" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="name"/><br/> 头像:<input type="file" name="imge"/><br/> <input type="submit" value="提交"/> </form> </body> </html>
在applicationcontext-mvc.xml中配置multipartresolver:
<!--配置文件上传解析器:id="multipartresolver",这个id不能乱写,还可以 设置一个maxuploadsize属性,就是上传文件的大小--> <bean id="multipartresolver" class="org.springframework.web.multipart.commons.commonsmultipartresolver"> <property name="maxuploadsize"> <value>2000000000</value> </property> </bean>
1.5. viewresolver视图解析器
前面我们在controller中返回modelandview结果视图时,如果是多个方法,需要一一返回结果视图,结果视图重复的内容还是需要写一遍,比较麻烦:
使用viewresolver视图解析器配置返回的结果视图.jsp,可以设置视图路径的前后缀,该配置可以让我们写视图路径的时间更加简单。
具体需要在applicationcontext-mvc.xml中配置如下内容:
<!--配置默认的视图解析器--> <bean class="org.springframework.web.servlet.view.internalresourceviewresolver"> <property name="prefix" value="/web-inf/views/" /> <property name="suffix" value=".jsp" /> </bean>
之后在controller中即可简化视图访问的写法:
@controller @requestmapping("/resolver") public class resolvercontroller { @requestmapping("/demo1") public modelandview demo1(){ modelandview modelandview = new modelandview(); modelandview.setviewname("resolver_demo1"); return modelandview; } @requestmapping("/demo2") public modelandview demo2(){ modelandview modelandview = new modelandview(); modelandview.setviewname("resolver_demo2"); return modelandview; } }
对应前台的页面访问:
上一篇: 网站没排名我照样日赚200的经历
下一篇: C++中自定义结构体或类作为关联容器的键