当前位置: 移动技术网 > IT编程>开发语言>Java > 【java框架】SpringMVC(3)--SpringMVC控制器常用业务操作

【java框架】SpringMVC(3)--SpringMVC控制器常用业务操作

2020年03月16日  | 移动技术网IT编程  | 我要评论

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;
    }
}

对应前台的页面访问:

 

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网