Web开发核心

转载:(99条消息) SpringBoot学习笔记(二)——Web开发_spring.web.resources.static-locations_Tracker_85的博客-CSDN博客

一、web开发

1、静态资源访问
静态资源放在以下路径中:/static (or /public or /resources or /META-INF/resources),就可以通过“项目根路径/静态资源名”来访问静态资源。
原理:静态映射/**拦截了所有请求,收到一个请求先跟所有Controller进行请求匹配,controller不能处理就都交给静态资源处理器,如果静态资源处理器也不能处理就返回404。

2、静态资源访问前缀
默认无前缀,修改静态资源访问前缀:

spring:
  mvc:
    static-path-pattern: "/res/**"
  • 1
  • 2
  • 3

此时访问路径“项目根路径/static-path-pattern/资源名”。

修改静态资源存放位置:

spring:
  web:
    resources:
      static-locations: [classpath:/ziyuan/]
  • 1
  • 2
  • 3
  • 4

此时,只有将静态资源放在spring.web.resources.static-locations指定的位置下才能被访问到。

3、欢迎页支持

  • 静态资源路径的index.html
    可以配置静态资源路径,但不能配置静态资源访问前缀,否则导致index.html不能被默认访问。
  • controller处理/index

4、favicon.ico
网站小图标,图片以favicon.ico命名,放在静态资源文件夹下,SpringBoot会自动识别。如果配置了静态资源访问前缀,此功能就失效了。

5、REST的使用

  • 使用HTTP请求方式动词表示对资源的操作。原来的方式:
@RequestMapping(value="/info",method=RequestMethod.GET)
  • 1
  • 核心filter:HiddenHttpMethodFilter
    用法:表单隐藏域携带,需要在SpringBoot中手动开启
<form action="/info" method="post">
    <input type="hidden" name="_method" value="put"/>
    <input type="submit" value="put请求,修改信息"/>
</form>
  • 1
  • 2
  • 3
  • 4

SpringBoot底层添加hiddenHttpMethodFilter组件代码:
WebMvcAutoConfiguration.class

    @Bean
	@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
	@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled")
	public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
		return new OrderedHiddenHttpMethodFilter();
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

开启restFul功能:

spring.mvc.hiddenmethod.filter.enabled=true
  • 1
  • 自定义HiddenHttpMtheodFilter
@Configuration
public class MyConfig {
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        //修改携带参数名称
        hiddenHttpMethodFilter.setMethodParam("_m");
        return hiddenHttpMethodFilter;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 派生注解:
HTTP请求 注解 操作
GET @GetMapping 获取
POST @PostMapping 保存
PUT @PutMapping 修改
DELETE @DeleteMapping 删除
    @GetMapping("/info")
    public String getMethod(){
        return "获取信息";
    }

    @PostMapping("/info")
    public String postMethod(){
        return "保存信息";
    }

    @PutMapping("/info")
    public String putMethod(){
        return "修改信息";
    }

    @DeleteMapping("/info")
    public String DeleteMapping(){
        return "删除信息";
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

使用时要注意路径不能有歧义性,例如:

@GetMapping("/stu/{id}")
@GetMapping("/stu{age}")
  • 1
  • 2

6、普通参数与基本注解
@PathVariable:路径变量
获取请求路径中的变量,如果参数是一个Map<String,String>类型,就将路径中的所有变量封装到该map中。

   <a href="/car/1/owner/zh">@PathVariable 路径变量</a>
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String,Object> getCar(@PathVariable("id") Integer id,
                                     @PathVariable("username") String username,
                                     @PathVariable Map<String,String> pv){
        Map<String,Object> map=new HashMap<>();
        map.put("id",id);
        map.put("username",username);
        map.put("pv",pv);
        return map;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

@RequestHeader:获取请求头
如果参数是一个Map<String,String>、MultiValueMap<String,String>、org.springframework.http.HttpHeaders HttpHeaders,就可以获取全部的请求头参数。

 @GetMapping("/car/2")
    public Map<String,Object> getHeader(@RequestHeader("User-Agent") String userAgent,
                                        @RequestHeader Map<String,String> headers){
        Map<String,Object> map=new HashMap<>();
        map.put("user-Agent",userAgent);
        map.put("headers",headers);
        return map;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

@ModelAttribute:从隐含模型中获取数据
该注解可以注释在方法上,也可以注释在方法入参处。注释在方法上,该方法会在controller方法执行前执行,如果该方法有返回值,就被放入到隐含模型中。注释在方法入参中,就从隐含模型中获取指定对象,如果没有就自动创建并放入到隐含模型中。

@ModelAttribute("user")
    public User addUser(){
        return new User("zhang","123456");
    }

    @GetMapping("/user")
    public User getUser(@ModelAttribute("user") User user){
        return user;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

@RequestParam:获取请求参数
获取请求路径“?”后面携带的参数。如果参数是一个Map<String,String>、MultiValueMap<String,String>,就可以将全部请求参数封装到map中。

  <a href="/user?age=1&inters=game&inters=basketball">
    @GetMapping("/user")
    public Map<String,Object> getHeader(@RequestParam("age") Integer age,
                                        @RequestParam("inters")List<String> inters,
                                        @RequestParam Map<String,String> params){
        Map<String,Object> map=new HashMap<>();
        map.put("age",age);
        map.put("inters",inters);
        map.put("params",params);
        return map;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

@CookieValue:获取Cookie值
如果参数类型为javax.servlet.http.Cookie,则可以获取全部Cookie值。

 @GetMapping("/user")
    public Map<String,Object> getCookie(@CookieValue("_ga")String ga,
    						@CookieValue("_ga)Cookie cookie){
    	Map<String,Object> map=new HashMap<>();
        map.put("_ga",ga);
        System.out.println(cookie.getName();
        return map;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

@RequestBody:获取请求体
可以获取表单中的k,v值,只有post请求才有请求体。

 @PostMapping("/user")
    public Map<String, Object> postMethod(@RequestBody String content){
        Map<String,Object> map=new HashMap<>();
        map.put("content",content);
        return map;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

@RequestAttribute:获取request域属性

  @GetMapping("/goto")
    public String gotoPage(HttpServletRequest request){
        request.setAttribute("msg","成功!");
        request.setAttribute("code","200");
        return "forward:/success";
    }
    
    @ResponseBody
    @GetMapping("/success")
    public Map<String,Object> success(@RequestAttribute("msg")String msg,
                                      @RequestAttribute("code")String code){
        Map<String,Object> map=new HashMap<>();
        map.put("msg",msg);
        map.put("code",code);
        return map;
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

@MatrixVariable:矩阵变量

  • 矩阵变量绑定在请求路径中
  • 需要在SpringBoot中手动开启
@Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void configurePathMatch(PathMatchConfigurer configurer) {
                UrlPathHelper urlPathHelper = new UrlPathHelper();
                urlPathHelper.setRemoveSemicolonContent(false);
                configurer.setUrlPathHelper(urlPathHelper);
            }
        };
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 若是有多个矩阵变量,应当使用英文符号;进行分隔
  • 若是一个矩阵变量有多个值,应当使用英文符号,进行分隔。或者命名多个重复的key即可
  • 如:/csr/sell;low=34;brand=byd,audi,yidi
<a href="/car/sell;low=34;brand=byd,yadi,audi">@MatrixVariable</a>
<a href="/car/sell;low=24;brand=byd;brand=yadi;brand=audi">@MatrixVariable</a>
<a href="/boss/1;age=20/2;age=10">@MatrixVariable /boss/{bossId}/{empId}</a>

    @ResponseBody
    @GetMapping("/car/{path}")
   public Map<String,Object> car(@MatrixVariable("low") Integer low,
                                 @MatrixVariable("brand")List<String> brand){
       Map<String,Object> map=new HashMap<>();
       map.put("low",low);
       map.put("brand",brand);
       return map;
   }

   @ResponseBody
   @GetMapping("/boss/{bossId}/{empId}")
   public Map<String,Object> boss(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,
                                  @MatrixVariable(value = "age",pathVar = "empId") Integer empAge){
       Map<String,Object> map=new HashMap<>();
        map.put("bossAge",bossAge);
        map.put("empAge",empAge);
       return map;
   }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

7、Web组件

7.1 拦截器
拦截器是SpringMVC中的一个对象,能拦截对Controller的请求,实现对请求的预处理。
**** 在SpringMVC中实现拦截器:****
1.创建类实现SpringMVC框架中的HandleInterceptor接口

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.在SpringMVC的配置文件中声明拦截器

	<!-- 拦截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**"/> 拦截所有请求
			<mvc:exclude-mapping path="/js/*"/>  放行静态资源
			<mvc:exclude-mapping path="/css/*"/>
			<mvc:exclude-mapping path="/images/*"/>
			<bean class="拦截器全限定名称"></bean>
		</mvc:interceptor>
	</mvc:interceptors>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

**** 在SpringBoot中使用拦截器 ****
1.创建拦截器类实现HandleInterceptor接口

public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 拦截请求
     * @param request 请求
     * @param response 响应
     * @param handler 被拦截的控制器对象
     * @return  true :请求被放行  false:请求被阶段
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("请求被拦截");
        return true;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.配置类实现WebMvcConfigurer接口,将拦截器注册到容器中

@Configuration
public class MyConfig implements WebMvcConfigurer {

    //向容器中注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //1.创建拦截器对象
        HandlerInterceptor interceptor=new LoginInterceptor();
        //指定拦截路径
        String[] path={"/user/**"};
        //指定不拦截路径
        String[] excludePath={"/user/login"};
        registry.addInterceptor(interceptor).addPathPatterns(path)
                                            .excludePathPatterns(excludePath);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

7.2 Servlet
在SpringBoot框架中使用Servlet对象。
使用步骤:
1.创建Servlet类。创建类继承HttpServlet

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //使用httpServletResponse输出数据,应答结果
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.println("执行Servlet");
        out.flush();
        out.close();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.向容器中注册Servlet

@Configuration
public class MyConfig{

    @Bean
    public ServletRegistrationBean<Servlet> servletRegistrationBean(){
        // public ServletRegistrationBean(T servlet, String... urlMappings)
        ServletRegistrationBean<Servlet> servlet = new ServletRegistrationBean<>();
        servlet.setServlet(new MyServlet());//添加Servlet
        servlet.addUrlMappings("/myServlet");//访问路径
        return servlet;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

7.3 Filter
Filter是Servlet规范中的过滤器,可以处理请求,对对象中的参数、属性进行调整。比如字符编码过滤器
1.创建Filter类实现Filter接口

public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("执行filter");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.注册Filter对象

@Configuration
public class MyConfig{

    @Bean
    public FilterRegistrationBean<Filter> filterRegistrationBean(){
        FilterRegistrationBean<Filter> filter = new FilterRegistrationBean<>();
        filter.setFilter(new MyFilter());
        filter.addUrlPatterns("/user/*");指定过滤地址
        return filter;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

7.4、字符集过滤器CharacterEncodingFilter
SpringBoot会自动配置字符编码过滤器,如需更改,有以下两种方式:
方式一:自定义CharacterEncodingFilter

@Configuration
public class MyConfig{

    @Bean
    public CharacterEncodingFilter characterEncodingFilter(){
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("utf-8");
        encodingFilter.setForceEncoding(true);
        return encodingFilter;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在配置文件中修改:

#使自动配置失效
server.servlet.encoding.enabled=false
  • 1
  • 2

方式二:修改配置文件
在配置文件中修改:

server.servlet.encoding.enabled=true
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true