Spring Boot 2.x快速上手(七)Spring Boot與Web開發

前言:Spring Boot幫我們簡化了架構的依賴和配置過程,但在Web開發層面上,仍然沿用Spring MVC開發的方式。


目錄

一、Spring Boot中請求頁面

二、AJAX的應用與處理

三、文件上傳的處理

四、獲取表單數據

五、404、500錯誤頁面

六、註冊Filter

七、替換Tomcat


本次的學習環節依舊是採用案例的方式來進行學習的,學習的教程相關資料和視頻也是可以找到的,如果有人需要源碼和視頻資源可以去下載和學習:https://edu.51cto.com/center/course/lesson/index?id=260193

我們先導入已經下載好的源碼,然後導入到ide中;

一、Spring Boot中請求頁面

1、Spring Boot中請求頁面分爲兩種情況:

  • 靜態頁面(直接放在/static目錄下,靜態頁面即可直接訪問)
  • 動態頁面(需要通過Controller跳轉到動態頁面,通過下面的兩個註解進行綁定)
    • @GetMapping
    • @RequestMapping(value = "/",method = RequestMethod.GET)

Spring MVC 中最重要的環節就是開發Controller控制器,在WebController中添加顯示頁面的代碼:

    //RequestMethod.GET 只有GET請求才能訪問這個方法,如果是Post則會提示405錯誤
    @RequestMapping(value = "/",method = RequestMethod.GET)
    public String index(){
        return "index";
    }

在application.properties文件中設置端口號爲80,緩存設置爲關閉,在啓動之前的還需要進行一下的設置,

然後啓動項目,到頁面上查看效果,

2、Controller獲取請求參數

  • 請求參數
    • 在方法參數前增加@RequestParam進行獲取
    • 如果參數名與頁面傳遞參數相同,則可以自動匹配完成注入
  • 路徑變量
    • 在方法參數前增加@PathVariable獲取uri中的參數

3、Controller中向頁面傳值

Controller中向頁面傳值主要有三種方式:

  • ModelAndView對象(推薦)
  • Model對象
  • WebRequest或者HttpServletRequest(不推薦)
    //在Spring MVC中常用的設置上下文有三種:
    /**
     * 1、ModelAndView
     * 2、Model
     * 3、WebRequest或者原生的HttpServletRequest對象
     */
    @RequestMapping(value = "/",method = RequestMethod.GET)
    public ModelAndView index(){

        ModelAndView mav = new ModelAndView("index");
        mav.addObject("emps",emps);
        return mav;
    }
//    //高內聚,低耦合的設計原則
//    public String index(Model model){
//        model.addAttribute("emp",emps);
//        return "index";
//    }
//    //setAttribute是向當前的請求中放入對象,這種方式與web容器強耦合
//    public String index(WebRequest req,HttpServletRequest request){
//        req.setAttribute("emps",emps);
//        request.setAttribute("emps",emps);
//        return  "index";
//
//    }

4、Thymeleaf頁面取值

在Thymeleaf中,讀取Controller傳入的數據需要使用${...}表達式進行獲取。

在index.jsp頁面中做如下的修改:

<html xmlns:th="http://www.thymeleaf.org">
<tr th:each="emp,stat:${emps}">
    <td th:text="${stat.index +1}"></td>
    <td>[[${emp.empno}]]</td>
    <td>[[${emp.ename}]]</td>
    <td>[[${emp.dname}]]</td>
    <td>[[${emp.job}]]</td>
    <td>[[${emp.hiredate}]]</td>
    <td style="color: red;font-weight: bold">[[${emp.sal}]]</td>
    <td style="text-align: center">
        <button class="btn btn-xs btn-info"></span>查看照片</button>
    </td>
</tr>

頁面展示:

二、AJAX的應用與處理

當點擊新增按鈕時彈出如下的界面:

部門的選項我們可以進行如下的操作,
1、在WebController中創建一個新的方法:

//@RequestMapping(value = "dept",method = RequestMethod.GET)
//AJAX返回的是JSON數據,而不是跳轉頁面
@GetMapping("/dept")
//@ResponseBody代表將返回值JSON序列化後送給瀏覽器,Spring Boot默認使用的JSON序列化工具是Jackson
@ResponseBody
public List<Dept> obtainDept(){
    return  depts;
}

2、在index.html中進行ajax的修改操作

            //點擊新增按鈕觸發
            $("#btnAdd").click(function () {
                //彈出對話框
                $('#dlgForm').modal()
                //$.ajax是jquery默認的ajax核心方法
                $.ajax({
                    url:"/dept",
                    type:"get",
                    dateType:"json",
                    success:function (json) {
                        //接收來自服務器的json字符串,並轉換爲json對象
                        console.log(json);
                        //清空原有的option選項
                        $("#dept").get(0).length=0;
                        for(var i =0;i < json.length;i++){
                            var d = json[i];
                            //.get(0)是獲取到原生的DOM對象
                            //只有原生對象纔有.option屬性
                            $("#dept").get(0).options.add(new Option(d.dname));

                        }
                    }
                })
            });

崗位和部門之間是一個二級聯動,即根據部門來選擇崗位,

在WebController中添加如下的代碼進行實現:

@GetMapping("/job")
@ResponseBody
public List<String> obtainDept(String d) {
    List<String> jobs = new ArrayList<String>();
    jobs.add("請選擇");
    if (d.equals("REASERCH")){
        jobs.add("CTO");
        jobs.add("Program");
    }else if(d.equals("SALES")){
        jobs.add("CSO");
        jobs.add("saler");
    }else if(d.equals("ACCOUNTING")){
        jobs.add("CFO");
        jobs.add("Cashier");
    }
    return jobs;
}

在index.html中進行ajax修改:

            //二級聯動
            $("#dept").change(function() {
                var dept = $(this).val();//獲取當前的部門
                $.ajax({
                    url:"/job?d="+dept,
                    dateType:"json",
                    data:"get",
                    success:function (json) {
                        //清空原有的屬性
                        $("#job").get(0).length = 0;
                        for(var i = 0;i<json.length;i++){
                            var job = json[i];
                            //.get(0)是獲取到原生的DOM對象
                            //只有原生對象纔有.options屬性
                            $("#job").get(0).options.add(new Option(job));
                        }
                    }
                })
            })

刷新頁面之後即可顯示級聯關係。

三、文件上傳的處理

頁面中有一個“員工照片”的上傳按鈕,即我們需要上傳一個照片文件上去,我們進行如下的代碼編寫,

在index.html中進行修改,

<!-- 網頁具備文件上傳的三個條件
   1、post提交
   2、form組件
   3、設置表單的enctype="multipart/form-data",默認表單的enctype是x-www-urlencoding
                -->
<form action="/create" method="post" enctype="multipart/form-data">

修改上傳按鈕的name屬性:name=“photo”

<input type="file" id="phone" name="photo">

在WebController中編寫文件上傳的代碼:

/**
* 文件上傳
* @param photo
* @return
*/
@PostMapping("/create")
//MultipartFile是上傳文件接口,對應了保存的臨時文件
//參數名與前端的name值保持一致
//@RequestParam("photo")代表了photo參數對應與前端name=photo的file框
public ModelAndView  create(@RequestParam("photo") MultipartFile photo) throws IOException {
    //String path ="E:/upload/";
    String fileanme = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
    String suffix =                       photo.getOriginalFilename().substring(photo.getOriginalFilename().lastIndexOf("."));
     if(!suffix.equals(".jpg")&&!suffix.equals(".png")){
        throw new RuntimeException("無效的圖片格式!");
     }
    //Spring提供了一個文件操作類FileCopyUtil
    //對上傳文件的複製,稱爲“歸檔”。
    FileCopyUtils.copy(photo.getInputStream(),new FileOutputStream(path+fileanme+suffix));
    return  null;
}

在application.properties文件中進行相關的設置;

#單個文件最大尺寸
spring.servlet.multipart.max-file-size=2mb
#一個請求最大的尺寸
spring.servlet.multipart.max-request-size=50mb
#自定義歸檔目錄
app.upload.location=E:/upload/

四、獲取表單數據

當我們新添加一個員工的信息的時候,就需要從前臺的表單獲取表單中的數據,

前後端的數據綁定要求所有的表單項與後臺實體bean的屬性名相同,依次按照bean實體的屬性名給前臺的表單項添加name屬性,然後在WebController中編寫獲取表單的數據:

@PostMapping("/create")
    //MultipartFile是上傳文件接口,對應了保存的臨時文件
    //參數名與前端的name值保持一致
    //@RequestParam("photo")代表了photo參數對應與前端name=photo的file框
    /**
     * 前後端數據綁定,後端使用bean接收,要求屬性和前端name保持一致就可以自動注入
     */
    public ModelAndView  create(Emp emp,@RequestParam("photo") MultipartFile photo) throws IOException {
        //String path ="E:/upload/";
        String fileanme = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
        String suffix = photo.getOriginalFilename().substring(photo.getOriginalFilename().lastIndexOf("."));
        if(!suffix.equals(".jpg")&&!suffix.equals(".png")){
            throw new RuntimeException("無效的圖片格式!");
        }
        emp.setPhotoFile(fileanme+suffix);
        emps.add(emp);//向數據源增加一個emp對象

        //Spring提供了一個文件操作類FileCopyUtil
        //對上傳文件的複製,稱爲“歸檔”。
        FileCopyUtils.copy(photo.getInputStream(),new FileOutputStream(path+fileanme+suffix));
        //頁面重定向到localhost
        //格式爲redirect:跳轉地址
        ModelAndView mav = new ModelAndView("redirect:/");
        return  mav;
    }

在此值得注意的是:需要重新創建一個ModelAndView進行頁面的重定向。

五、404、500錯誤頁面

六、註冊Filter

搭載過濾器就需要的入口類中註冊Filter,

//在入口類中註冊Filter
//@Bean會將方法中的放回對象在SB啓動的時候放入IoC容器中
@Bean
public FilterRegistrationBean filterRegiste(){
    FilterRegistrationBean  regFilter = new FilterRegistrationBean();
    //創建並註冊AccessRecordFilter
    regFilter.setFilter(new AccessRecordFilter());
    //對所有請求進行攔截
    regFilter.addUrlPatterns("/*");
    //設置過濾器名字
    regFilter.setName("AccessRecorder");
    //設置排序,如果系統中有多個過濾器,Order就決定了那個過濾器就先執行,數字越小越靠前執行
    regFilter.setOrder(1);
    return  regFilter;
}

創建一個過濾器類,

public class AccessRecordFilter implements Filter {
    private Logger logger = LoggerFactory.getLogger(AccessRecordFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest  request = (HttpServletRequest) servletRequest;
        String uri= request.getRequestURI();
        if(uri.endsWith(".css")||uri.endsWith(".js")||uri.endsWith(".jpg")||uri.endsWith(".png")){
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }
        String ua = request.getHeader("user-agent");
        String ip = request.getRemoteAddr();
        Long st = new Date().getTime();
        //將請求向後送到Controller進行處理
        filterChain.doFilter(servletRequest,servletResponse);
        Long et = new Date().getTime();
        logger.info("url:{},ip:{},time:{}ms,ua:{}",uri,ip,(et-st),ua);



    }

    @Override
    public void destroy() {

    }
}

完成之後在我們的控制檯可以打印出相關的信息。

七、替換Tomcat

Spring Boot支持三種內嵌的web容器:

  1. Tomcat (默認),是最流行的web容器
  2. Jetty :性能優秀的web容器,適用於長連接
  3. Undertow:非阻塞web容器,性能優異,適用於高併發

在實際的開發過程中就效率來看,Jetty是完全碾壓Tomcat的,但目前來看大多的情況下還是使用Tomcat的。

替換的過程只是在pom文件中對容器的包進行修改即可,不需要其他的操作。

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
<!--		<dependency>-->
<!--			<groupId>org.springframework.boot</groupId>-->
<!--			<artifactId>spring-boot-starter-jetty</artifactId>-->
<!--		</dependency>-->
<!--		<dependency>-->
<!--			<groupId>org.springframework.boot</groupId>-->
<!--			<artifactId>spring-boot-starter-undertow</artifactId>-->
<!--		</dependency>-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
<!--			<exclusions>-->
<!--				<exclusion>-->
<!--					<artifactId>spring-boot-starter-tomcat</artifactId>-->
<!--					<groupId>org.springframework.boot</groupId>-->
<!--				</exclusion>-->
<!--			</exclusions>-->
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章