SpringMVC + json

SpringMVC + json

1. 導包及初始化配置

1.1 導包

spring-mvc需要的包:
	spring核心包
	spring-web
	spring-webmvc
json需要的包:
	jackson-core
	jackson-databind
	jackson-annotations

1.2 mavne依賴

<!--springmvc框架-->                      
<dependency>                            
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>   
  <version>5.1.5.RELEASE</version>      
</dependency>                           
<dependency>                            
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.1.5.RELEASE</version>      
</dependency> 

<!--json包(Springmvc默認使用jackson)-->             
<dependency>                                   
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>    
  <version>2.9.8</version>                     
</dependency>                                  
<dependency>                                   
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>        
  <version>2.9.8</version>                     
</dependency>                                  
<dependency>                                   
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId> 
  <version>2.9.8</version>                     
</dependency>                                  

1.3 配置前端(核心)控制器

  • web.xml中配置前端控制器。
<!--配置springmvc核心控制器-->
<servlet>
  <servlet-name>springmvc</servlet-name>                                          
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param> 
    <!--
      contextConfigLocation配置springmvc加載的配置文件(配置處理器、映射器、適配器等等)
      如果不配置contextConfigLocation,默認加載WEB-INF/servlet名稱-servlet.xml(springmvc-servlet.xml)
    -->
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </init-param>
  <!--在tomcat啓動的時候就創建核心控制器-->
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>springmvc</servlet-name>
	<!--
        url-pattern:
            第一種:*.action,訪問以.action結尾由DispatcherServlet進行解析。
            第三種:/,所有訪問的地址都由DispatcherServlet進行解析,但對於靜態文件的解析需要配置不讓DispatcherServlet進行解析。
            第三種:/*,錯誤的配置方法,運行結果報錯。
	-->
  <url-pattern>/</url-pattern> 
</servlet-mapping>

1.4 配置靜態資源放行

  • applicationContext.xml中配置靜態資源放行。
<!--靜態資源放行-->
<mvc:default-servlet-handler/>

2. 實現控制器的三種方式

2.1 實現Controller接口

  • 實現Controller接口
public class ControllerOne implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
       return null;
    }
}
  • applicationContext.xml配置controller對應的bean
<!-- name:配置controller的訪問路徑 -->
<bean name="/my1.do" class="com.yogie.controller.ControllerOne"></bean>

2.2 實現HttpRequestHandler接口

public class ControllerTwo implements HttpRequestHandler {
    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
    }
}
  • 配置bean
<bean name="/my2" class="com.yogie.controller.ControllerTwo"></bean>

2.3 全註解的方式

2.3.1 開啓註解支持和註解掃描

  • applicationContext.xml中配置開啓註解
<!--開啓註解支持-->
<mvc:annotation-driven/>
<!--開啓註解掃描-->
<context:component-scan base-package="com.yogie.controller"/>
@Controller
@RequestMapping("/my3")
public class ControllerThree {
    @RequestMapping("/test")
    public String test(){
        return null;
    }
}

2.3.2 springmvc註解大全

1@Component 表示一個組件(類),把當前組件加入IOC容器,加入容器的組件的名稱默認是類名且第一個字母小寫。@Component("userDao")//相當於:<bean id="userDao" class=...> 可簡化爲:@Component
2@Repository 表示是一個持久層的組件
3@Service 表示是一個業務邏輯層的組件
4@Controller 表示是一個控制層的組件
5@Scope"prototype")指定對象單例還是多例
6@Resource 默認根據修飾的字段名稱會去IOC容器找對象自動注入,如果名稱沒有找到,在根據類型查找。如果該類型在IOC容器有多個對象,報錯!根據類型沒有找到對象,報錯!
7、Resource(name="") 會根據指定的名稱去容器找對象自動注入。

3. 獲取參數的四種形式

3.1 直接獲取

@RequestMapping("/param1")
//前臺地址:localhost/param1?password=123&name=tom
public ModelAndView param1(String name,String password){
    //前臺傳遞過來的參數名與方法的參數名必須一致,順序可以不一致
	return null;
}
@RequestMapping("/param2")
//前臺地址:localhost/param2?password=123&username=tom
//解決前臺後臺參數名字不一致的情況
public ModelAndView param2(@RequestParam("username")String name, String password){
	return null;
}

3.2 封裝到Javabean對象

@RequestMapping("/param3")
//前臺地址:localhost/param3?pwd=123&name=tom
public ModelAndView param3(User user){
    return null;
}

3.3 通過HttpServletRequest對象

@RequestMapping("/param4")
//前臺地址:localhost/param4?password=123&name=tom
public ModelAndView param4(HttpServletRequest request){
    //通過request對象的getParameter()方法獲取值
    String name = request.getParameter("name");
    return null;
}

3.4 Restful風格傳遞參數

@RequestMapping("/param5/GET/{name}/{pwd}")
//前臺地址:localhost/param5/GET/tom/123
//注意:使用restful風格傳遞多個參數時,前臺的參數順序與方法的形參要一致。
public ModelAndView param5(@PathVariable("name")String name,@PathVariable("pwd")String password){
	return null;
}

4. 返回數據及視圖的五種方式

  • 配置視圖解析器
<!--配置視圖解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--前端-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--後綴-->
    <property name="suffix" value=".jsp"/>
</bean>

4.1 Model方式

public String returnData1(Model model){
    //實際上將數據放入到了request域中
    model.addAttribute("name","tom");
    User user = new User("tom","123");
    //前臺通過user來獲取User對象的數據
    model.addAttribute(user);
    //返回視圖名稱:配置了視圖解析器,會自動添加前綴後後綴
    return "list";
}

4.2 ModelAndView方式

public ModelAndView returnData2(){
    ModelAndView mv = new ModelAndView();
    mv.addObject("name","tom");
    //設置視圖
    mv.setViewName("list");
    return mv;
}

4.3 HttpServletRequest方式

public void returnData3(HttpServletRequest request,HttpServletResponse response){
    request.setAttribute("name","tom");
    //轉發的方式,不會走視圖解析器
    request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request,response);
}

4.4 直接返回對象

@RequestMapping("/data")
//這種情況返回的是默認視圖,即:data.jsp
//data.jsp中可以獲取到user對象的數據
public User returnData4(){
	User user = new User("adf","123");
	return user;
}

4.5 返回json數據

@RequestMapping("/data5")
@ResponseBody//添加這個註解後,數據將會以json的格式返回到前臺,不會返回視圖
public List<User> returnData5(){
    List<User> list = Arrays.asList(...);
    return list;
}
//注意:如果User對象中有日期類型的字段,需要給對應的get、set方法添加屬性。
public class User{
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    public Date getDate() {
        return date;
    }

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public void setDate(Date date) {
        this.date = date;
    }
}

5. 請求轉發與重定向

​ 控制器中的視圖設置,以下這兩種情況都不會進入視圖解析器的配置中加前綴後綴。但是區別於不加forward和redirect關鍵字的情況:如果不加這兩個關鍵字,一定會進入視圖解析器加前綴後綴。

5.1 轉發

@RequestMapping("/forward")
public String forwordPage(){
    return "forward:WEB-INF/jsp/hello.jsp";
}

5.2 重定向

@RequestMapping("/redirect")
public String redirectPage(){
    return "redirect:index.html";
}

6. 解決Springmvc中文亂碼問題

<!--springmvc亂碼過濾器-->
<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>

6. 文件上傳與下載

6.1 配置文件上傳解析器

<!--文件上傳解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--配置文件上傳的最大尺寸爲:100kb-->
    <property name="maxUploadSize" value="102400"/>
</bean>

6.1 文件上傳

@RequestMapping(path = "/upload",method = RequestMethod.POST)
    public String upload(String name, MultipartFile upload, HttpServletRequest request) throws IOException {
        System.out.println("post方法");
        System.out.println("其他屬性name::" + name);
        System.out.println("上傳文件的類型:" + upload.getContentType());
        System.out.println("上傳文件名稱:" + upload.getName());
        System.out.println("上傳文件文件名:" + upload.getOriginalFilename());

        // 上傳的流
        InputStream inputStream = upload.getInputStream();
        // 獲取webapp路徑
        String webapp = request.getServletContext().getRealPath("/uploads/");
        System.out.println(webapp);
        /*File file = new File(webapp, upload.getOriginalFilename());
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            // 如果upload文件夾不存在,就創建
            parentFile.mkdirs();
        }
        // 拷貝到webapp一個目錄裏面
        IOUtils.copy(inputStream, new FileOutputStream(file));*/
        return "upload";

    }

6.2 文件下載

@RequestMapping("/download")
public void download(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    //解決文件名中文亂碼,對文件名進行utf-8編碼
    String encode = URLEncoder.encode("springmvc執行流程.jpg", "UTF-8");
    resp.setCharacterEncoding("utf-8");
    //設置建議的下載文件名
    resp.setHeader("Content-Disposition", "filename=springmvc執行流程.jpg");
    //設置文件名的類型,查w3cschool中HTTP content-type對照表
    resp.setHeader("Content-Type", "application/x-img");
    // 準備文件
    String webapp = req.getServletContext().getRealPath("/uploads/");
    File file = new File(webapp, "springmvc執行流程.jpg");
    FileInputStream inputStream = new FileInputStream(file);
    IOUtils.copy(inputStream, resp.getOutputStream());
}

7. SpringMVC的執行流程

7.1 springmvc工作流程圖解

springmvc執行流程.jpg

7.2 springmvc工作流程詳解

首先應清楚:控制器Controller = 處理器Handler
  1. 用戶發送請求至前端控制器DispatcherServlet。
  2. DispatcherServlet收到請求調用HandlerMapping處理器映射器。
  3. 處理器映射器找到具體的處理器(可以根據xml配置、註解進行查找),生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。
  4. DispatcherServlet調用HandlerAdapter處理器適配器(附註:如果成功獲得HandlerAdapter後,此時將開始執行攔截器的preHandler(…)方法)。
  5. HandlerAdapter經過適配調用具體的處理器(Controller)。調用之前有一個入參的過程,在Handler的入參過程中,如果有配置,spring還會做一些額外的工作:
HttpMessageConveter:將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息
數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等
數據格式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等
數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中
  1. Controller執行完成返回ModelAndView。
  2. HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。
  3. DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器。
  4. ViewReslover解析後返回具體View,這個view僅僅是一個頁面(視圖)名字,且沒有後綴名。
  5. DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。
  6. DispatcherServlet響應用戶。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章