甘肃可以种植紫玉兰吗?

小说:甘肃可以种植紫玉兰吗?作者:宗宗开更新时间:2019-05-20字数:14666

前言

前面学习了简单的Spring Web知识,接着学习更高阶的Web技术。

高级技术

Spring MVC配置的替换方案

自定义DispatcherServlet配置

在第五章我们曾编写过如下代码。


public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

}

可以看到SpitterWebinitializer实现了AbstractAnnotationConfigDispatcherServletInitializer抽象类,并重写了三个必须的方法,实际上还可对更多方法进行重写,以便实现额外的配置,如对customizeRegistration方法进行重写,该方法是AbstractDispatcherServletInitializer的方法,无实际的方法体。当AbstractAnnotationConfigDispatcherServletInitializerDispatcherServlet注册到Servlet容器中后,就会调用customizeRegistration方法,并将Servlet注册后得到的Registration.Dynamic传入。可通过重写customizeRegistration方法设置MultipartConfigElement,如下所示。


    @Override
    protected void customizeRegistration(Dynamic registration) {
        registration.setMultipartConfig(
                new MultipartConfigElement("/tmp/spittr/uploads"));
    }

添加其他Servlet和Filter

AbstractAnnotationConfigDispatcherServletInitializer会创建DispatcherServletContextLoaderListener,当需要添加其他ServletFilter时,只需要创建一个新的初始化器即可,最简单的方式是实现WebApplicationInitializer接口。


import org.springframework.web.WebApplicationInitializer;

import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

public class MyServletInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext servletContext) throws ServletException {
        Dynamic servlet = servletContext.addServlet("myServlet", MyServlet.class);
        servlet.addMapping("/custom/**");

        FilterRegistration.Dynamic filter = servletContext.addFilter("myFilter", MyFilter.class);
        filter.addMappingForUrlPatterns(null, false, "/custom/*");

    }
}

在xml文件中声明DispatcherServlet

对基本的Spring MVC应用而言,需要配置DispatcherServletContextLoaderListenerweb.xml配置如下。


<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
  </context-param>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  
</web-app>

可以看到在web.xml中配置了DispatcherServletContextLoaderListener,并且定义了上下文,该上下文会被ContextLoaderListener加载,从中读取bean。也可指定DispatcherServlet的应用上下文并完成加载,配置web.xml如下。


  <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

上面使用DispatcherServletContextLoaderListener加载各自的上下文,但实际情况中,基于Java的配置更为通用,此时只需要配置DispatcherServletContextLoaderListener使用AnnotationConfigWebApplicationContext,这样它便可加载Java配置类,而非使用xml,可设置contextClassDispathcerServlet的初始化参数,如下所示。


<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
  </context-param>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>ch7.RootConfig</param-value>
  </context-param>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextClass</param-name>
      <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>
    
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>ch7.WebConfig</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

处理multipart形式数据

处理multipart数据主要用于处理文件上传操作。需要配置multipart解析器读取multipart请求。

配置multipart解析器

DispatcherServlet并未实现任何解析multipart请求数据功能,它只是将任务委托给MultipartResolver策略接口实现,通过该实现解析multipart请求内容,Spring中内置了CommonsMultipartResolverStandardServletMultipartResolver两个解析器。

  • 使用StandardServletMultipartResolver

使用Java配置如下


@Override

protected void customizeRegistration(Dynamic registration) {
    registration.setMultipartConfig(new MultipartConfigElement("/tmp/spittr/uploads", 2 * 1024 * 1024, 4 * 1024 * 1024, 0));
}

使用xml配置如下,在servlet标签中配置multipart-config


      <multipart-config>
        <location>/tmp/spittr/uploads</location>
        <max-file-size>2 * 1024 * 1024</max-file-size>
        <max-request-size>4 * 1024 * 1024</max-request-size>
      </multipart-config>
  • 使用CommonsMultipartResolver

使用Java配置如下


    @Bean
    public MultipartResolver multipartResolver() throws IOException {
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
        commonsMultipartResolver.setUploadTempDir(new FileSystemResource("/tmp/spittr/uploads"));

        return commonsMultipartResolver;
    }

处理multipart请求

可在控制器的方法参数上添加@RequestPart注解,如下所示。


@RequestMapping(value="/register", method=POST)
public String processRegistration(
    @RequestPart("profilePicture") byte[] profilePicture,
    @Valid Spittr spitter,
    Errors errors) {
    profilePicture.transferTo(new File("/data/spittr" + profilePicture.getOriginalFilename()));
}

处理异常

Spring提供了多种方式将异常转换为响应

  • 特定的异常将会自动映射为指定的HTTP状态码。
  • 异常上可以添加@ResponseStatus注解,从而将其映射为某个HTTP状态码。
  • 在方法上可添加@ExceptionHandler注解,使其用来处理异常。

将异常映射为HTTP状态码

Spring异常与状态码对应关系如下。

编写异常处理方法

可在请求中直接使用try/catch处理异常,其与正常Java方法中的try/catch相同,同时,也可编写处理器来处理特定异常,当出现特定异常时,将有处理器委托方法进行处理。


@ExceptionHandler(DuplicateSpittleException.class)
public String handleDuplicateSpittle() {
    return "error/duplicate";
}

为控制器添加通知

控制器通知是任意带有@ControllerAdvice注解的类,该类包含如下类型的一个或多个方法。

  • @ExceptionHandler注解标注的方法。
  • @InitBinder注解标注的方法。
  • @ModelAttribute注解标注的方法。

上面方法会运用到整个应用程序所有控制器中带有@RequestMapping注解的方法上。


@ControllerAdvice
public class AppWideExceptionHandler {
    @ExceptionHandler(DuplicateSpittleException.class)
    public String duplicateSpittleHandler() {
        return "error/duplicate";
    }
}

经过上述配置,任意控制器方法抛出了DuplicateSpittleException异常,都会调用这个duplicateSpittleHandler方法处理异常。

跨重定向请求传递数据

对于重定向而言,若需要从发起重定向的方法传递数据给处理重定向方法中,有如下两种方法

  • 使用URL模版以路径变量和/或查询参数形式传递数据。
  • 通过flash属性发送数据。

通过URL模版进行重定向

如前面讲到的通过redirect:/spitter/{username}进行重定向,该方法会直接根据username确定url,并非十分安全的做法,可使用进行如下处理。


model.addAttribute("username", spitter.getUsername());
return "redirect:/spitter/{username}";

当需要传递参数,如id时,可进行如下处理。


model.addAttribute("username", spitter.getUsername());
model.addAttribute("spitterId", spitter.getId());
return "redirect:/spitter/{username}";

usernameleesfid123456。这样访问的url/spitter/leesf?spitterId=123456。这种方法只能传递简单的值,无法发送更为复杂的值,此时需要使用flash属性。

使用flash属性

通过RedirectAttributes设置flash属性,这样可直接传递对象。


@ReuqestMapping(value="/register", method=POST)
public String processRegistration(Spitter spitter, RedirectAttributes model) {
    spitterRepository.save(spitter);
    model.addAttribute("username", spitter.getUsername());
    model.addFlashAttribute("spitter", spitter);
    return "redirect:/spitter/{username}";
}

这样spitter对象也被传递到重定向页面中,可直接访问spitter对象。

总结

本篇博文讲解了如何配置DispatcherServletContextLoaderListener,以及如何处理异常和控制器通知,最后分析如何在重定向时传递数据。

当前文章:http://www.cnsdbtzg.com/6g5hy/38799.html

发布时间:2019-05-20 12:03:23

【中华红霞杨】中华红霞杨_价格_图片_产地报价表 日本红枫树5公分多少钱? 小叶女贞种植密度是多少? 5公分苦楝树苗价格 白三叶播种时间 只有到了这里才知道凌霄花原来还可以这么艳,事实就是如此哦! 绿化工地中的丰花月季种植密度一平方米多少棵合适 紫荆花种植基地在哪里? 贵州可以种植北美海棠吗? 13公分白玉兰批发基地在哪里?

33445 66634 93687 29022 22865 35447 79400 15720 35903 19779 79523 68381 84760 31759 59853 87533 50843 59554 78193 13302 63157 50324 65700

我要说两句: (0人参与)

发布