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>
发布了98 篇原创文章 · 获赞 165 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/cyl101816/article/details/100070376