【java框架】SpringMVC(3)--SpringMVC控制器經常使用業務操做

1. SpringMVC控制器業務操做

在SpringMVC第二節中咱們瞭解到mvc控制器處理頁面url請求返回響應視圖,除了這些操做外,控制器還須要處理更重要的業務,如:接收前臺頁面傳遞的參數、綁定數據到頁面、返回json數據、文件上傳、文件下載等業務操做。html

1.1.參數接收

1.1.1.  配置請求編碼過濾器

SpringMVC框架自己沒有處理請求編碼,在前臺參數接收Post請求的時候,可能會出現編碼亂碼的問題,而Spring框架爲咱們提供了一個請求編碼過濾器,咱們只須要在web.xml中配置一個請求編碼過濾器便可:java

web.xml中配置UTF-8編碼以下:web

<?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接收方式:spring

①    使用方法的形參接收:注意形參要和請求參數一致;apache

@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參數傳遞方式:json

http://localhost:8080/paramController/insert?username=」青海」&age=21restful

獲取到的參數信息:mvc

 

②    若是形參名稱和前臺傳入的參數名不一致,須要使用@RequestParam(value=」前臺參數名」)進行映射對應;app

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

對應前臺的頁面訪問:

 

 

相關文章
相關標籤/搜索