springmvc(4)

简介: springmvc

springmvc(3)https://developer.aliyun.com/article/1530455

9.4、@ResponseBody响应浏览器json数据

服务器处理ajax请求之后,大多数情况都需要向浏览器响应一个java对象,此时必须将java对象转换为

json字符串才可以响应到浏览器,之前我们使用操作json数据的jar包gson或jackson将java对象转换为

json字符串。在SpringMVC中,我们可以直接使用@ResponseBody注解实现此功能

@ResponseBody响应浏览器json数据的条件:

1、导入jackson的依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.1</version>
</dependency>

2、SpringMVC的配置文件中设置开启mvc的注解驱动

<!--开启mvc的注解驱动-->
<mvc:annotation-driven />

3、使用@ResponseBody注解标识控制器方法,在方法中,将需要转换为json字符串并响应到浏览器

的java对象作为控制器方法的返回值,此时SpringMVC就可以将此对象直接转换为json字符串并响应到浏览器

<input type="button" value="测试@ResponseBody响应浏览器json格式的数据"@click="testResponseBody()"><br>
<script type="text/javascript" th:src="@{/js/vue.js}"></script>
<script type="text/javascript" th:src="@{/js/axios.min.js}"></script>
<script type="text/javascript">
    var vue = new Vue({
        el:"#app",
        methods:{
            testResponseBody(){
                axios.post("/SpringMVC/test/ResponseBody/json").then(response=>{
                    console.log(response.data);
                });
            }
        }
    });
</script>
//响应浏览器list集合
@RequestMapping("/test/ResponseBody/json")
@ResponseBody
public List<User> testResponseBody(){
    User user1 = new User(1001,"admin1","123456",23,"男");
    User user2 = new User(1002,"admin2","123456",23,"男");
    User user3 = new User(1003,"admin3","123456",23,"男");
    List<User> list = Arrays.asList(user1, user2, user3);
    return list;
}
//响应浏览器map集合
@RequestMapping("/test/ResponseBody/json")
@ResponseBody
public Map<String, Object> testResponseBody(){
    User user1 = new User(1001,"admin1","123456",23,"男");
    User user2 = new User(1002,"admin2","123456",23,"男");
    User user3 = new User(1003,"admin3","123456",23,"男");
    Map<String, Object> map = new HashMap<>();
    map.put("1001", user1);
    map.put("1002", user2);
    map.put("1003", user3);
    return map;
}
//响应浏览器实体类对象
@RequestMapping("/test/ResponseBody/json")
@ResponseBody
public User testResponseBody(){
    return user;
}

常用的Java对象转换为json的结果:

实体类–>json对象

map–>json对象

list–>json数组(方括号包裹的)

9.5、@RestController注解

@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了

@Controller注解,并且为其中的每个方法添加了@ResponseBody注解

10、文件上传和下载

10.1、文件下载

ResponseEntity:可以作为控制器方法的返回值,表示响应到浏览器的完整的响感报文

ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文

使用ResponseEntity实现下载文件的功能

真实地址的样子

文件分隔符的表示File.separator

is.available()获取流的字节数

@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws
    IOException {
    //通过session获取ServletContext对象
    ServletContext servletContext = session.getServletContext();
    //获取服务器中文件的真实路径
    String realPath = servletContext.getRealPath("/static/img/1.jpg");
    //创建输入流
    InputStream is = new FileInputStream(realPath);
    //创建字节数组
    byte[] bytes = new byte[is.available()];
    //将流读到字节数组中
    is.read(bytes);
    //创建HttpHeaders对象设置响应头信息
    MultiValueMap<String, String> headers = new HttpHeaders();
    //Content-Disposition设置要下载方式
    //attachment以附件的方式进行下载
    //设置下载文件的名字
    headers.add("Content-Disposition", "attachment;filename=1.jpg");
    //设置响应状态码
    HttpStatus statusCode = HttpStatus.OK;
    //创建ResponseEntity对象
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers,statusCode);
    //关闭输入流
    is.close();
    return responseEntity;
}

10.2、文件上传

文件上传要求form表单的请求方式必须为post,并且添加属性enctype="multipart/form-data"

SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息

上传步骤:

①添加依赖:

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

②在SpringMVC的配置文件中添加配置:

<!--配置文件上传解析器 id必须配置为固定值,因为springmvc是靠id来获取这个解析器的-->  
<!--  单例的情况下,他的实例化过程是在获取ioc容器的时候执行-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

③控制器方法:

@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
    //获取上传的文件的文件名
    String fileName = photo.getOriginalFilename();
    //处理文件重名问题
    String hzName = fileName.substring(fileName.lastIndexOf("."));
    fileName = UUID.randomUUID().toString() + hzName;
    //获取服务器中photo目录的路径
    ServletContext servletContext = session.getServletContext();
    String photoPath = servletContext.getRealPath("photo");
    File file = new File(photoPath);
    if(!file.exists()){
        file.mkdir();
    }
    String finalPath = photoPath + File.separator + fileName;
    //实现上传功能
    photo.transferTo(new File(finalPath));
    return "success";
}

11、拦截器

过滤器是在浏览器和目标资源之间过滤

11.1、拦截器的配置

SpringMVC中的拦截器用于拦截控制器方法的执行

SpringMVC中的拦截器需要实现HandlerInterceptor

SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置:

<mvc:interceptors>
    <bean class="com.atguigu.interceptor.FirstInterceptor"></bean>
</mvc:interceptors>
<bean class="com.atguigu.interceptor.FirstInterceptor"></bean>
<!-- 以上两种配置方式都是对DispatcherServlet所处理的所有的请求进行拦截 -->
<mvc:interceptors>
    <mvc:interceptor>
       <!-- /*是处理一层目录的请求 /**是所有请求-->
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/testRequestEntity"/>
        <ref bean="firstInterceptor"></ref>
    </mvc:interceptor>
</mvc:interceptors>
<!--
    以上配置方式可以通过ref或bean标签设置拦截器,通过mvc:mapping设置需要拦截的请求,
    通过mvc:exclude-mapping设置需要排除的请求,即不需要拦截的请求
-->

11.2、拦截器的三个抽象方法

这三个方法不管控制器方法有没有都会执行

SpringMVC中的拦截器有三个抽象方法:

preHandle:控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法

postHandle:控制器方法执行之后执行postHandle()

afterCompletion:处理完视图和模型数据,渲染视图完毕之后执行afterCompletion()

11.3、多个拦截器的执行顺序

①若每个拦截器的preHandle()都返回true

此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:preHandle()会按照配置的顺序执行,而postHandle()和afterCompletion()会按照配置的反序执行

②若某个拦截器的preHandle()返回了false

preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterCompletion()会执行

12、异常处理器

控制器方法执行的过程中如果出现了异常,那么就可以通过springmvc给我们提供的一个接口来处理异常

12.1、基于配置的异常处理

SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver

HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和

SimpleMappingExceptionResolver

SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver,使用方式:

<bean
      class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--
                properties的键表示处理器方法执行过程中出现的异常
                properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面
      -->
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
    <!--
            exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域中进行共享
            这里的ex就是异常信息在请求域中的属性名
        -->
    <property name="exceptionAttribute" value="ex"></property>
</bean>

出现了异常就会往我们设置好的页面去跳

获取请求域中共享的异常信息

<p th:text="${ex}"></p>

12.2、基于注解的异常处理

//@ControllerAdvice将当前类标识为异常处理的组件
@ControllerAdvice
public class ExceptionController {
    //@ExceptionHandler用于设置所标识方法处理的异常
    @ExceptionHandler(ArithmeticException.class)
    //ex表示当前请求处理中出现的异常对象
    public String handleArithmeticException(Exception ex, Model model){
        model.addAttribute("ex", ex);
        return "error";
    }
}

13、注解配置SpringMVC

使用配置类和注解代替web.xml和SpringMVC配置文件的功能

13.1、创建初始化类,代替web.xml

在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。 Spring提供了这–…+个接口的实现,名为

SpringServletContainerInitializer,这个类反过来又会查找实现WebApplicationInitializer的类并将配置的任务交给它们来完成。Spring3.2引入了一个便利的WebApplicationInitializer基础实现,名为AbstractAnnotationConfigDispatcherServletInitializer,当我们的类扩展了

AbstractAnnotationConfigDispatcherServletInitializer并将其部署到Servlet3.0容器的时候,容器会自动发现它,并用它来配置Servlet上下文。用来代替web.xml

public class WebInit  extends AbstractAnnotationConfigDispatcherServletInitializer {
    //设置一个配置类代替spring配置文件
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }
    @Override
    //设置一个配置类代替springmvc的配置文件
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }
    @Override
    //设置springMVC的前端控制器Dispatcherservlet的url-pattern
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    @Override
    //来设置当前的过滤器
    protected Filter[] getServletFilters() {
        //创建编码过滤器
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");
        encodingFilter.setForceRequestEncoding(true);
        //创建处理请求方式的过滤器
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[]{encodingFilter, hiddenHttpMethodFilter};
    }
}

13.2、创建SpringConfig配置类,代替spring的配置文件

//@Configuration将当前类表示为配置类
@Configuration
public class SpringConfig {
    //ssm整合之后,spring的配置信息写在此类中
}

13.3、创建WebConfig配置类,代替SpringMVC的配置文件

//代替springmvc的配置文件  
@Configuration  
//扫描主件  
@ComponentScan("com.atguigu.controller")  
//开启注解驱动  
@EnableWebMvc  
public class WebConfig implements WebMvcConfigurer {  
    //使用默认的servlet处理静态资源  
    @Override  
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {  
        configurer.enable();  
    }  
    //配置文件上传解析器,@Bean注解可以将标识的方法的返回值作为bean进行管理,bean的id为方法的方法名  
    @Bean  
    public CommonsMultipartResolver multipartResolver(){  
        return new CommonsMultipartResolver();  
    }  
    //配置拦截器  
    @Override  
    public void addInterceptors(InterceptorRegistry registry) {  
        FirstInterceptor firstInterceptor = new FirstInterceptor();  
        registry.addInterceptor(firstInterceptor).addPathPatterns("/**");  
    }  
    //配置视图控制  
    @Override  
   public void addViewControllers(ViewControllerRegistry registry) {  
      registry.addViewController("/").setViewName("index");  
   }  
    //配置异常映射  
    @Override  
   public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {  
      SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();  
      Properties prop = new Properties();  
      prop.setProperty("java.lang.ArithmeticException", "error");  
      //设置异常映射  
      exceptionResolver.setExceptionMappings(prop);  
      //设置共享异常信息的键  
      exceptionResolver.setExceptionAttribute("ex");  
      resolvers.add(exceptionResolver);  
   }  
    //配置生成模板解析器  
    @Bean  
    public ITemplateResolver templateResolver() {  
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();  
        // ServletContextTemplateResolver需要一个ServletContext作为构造参数,可通过WebApplicationContext 的方法获得  
        ServletContextTemplateResolver templateResolver = new  
                ServletContextTemplateResolver(webApplicationContext.getServletContext());  
        templateResolver.setPrefix("/WEB-INF/templates/");  
        templateResolver.setSuffix(".html");  
        templateResolver.setCharacterEncoding("UTF-8");  
        templateResolver.setTemplateMode(TemplateMode.HTML);  
        return templateResolver;  
    }  
    //生成模板引擎并为模板引擎注入模板解析器(保证参数名和提供这个参数的方法名一致即可)  
    @Bean  
    public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {  
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();  
        templateEngine.setTemplateResolver(templateResolver);  
        return templateEngine;  
    }  
    //生成视图解析器并未解析器注入模板引擎  
    @Bean  
    public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {  
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();  
        viewResolver.setCharacterEncoding("UTF-8");  
        viewResolver.setTemplateEngine(templateEngine);  
        return viewResolver;  
    }  
}

13.4、测试功能

@RequestMapping("/")
public String index(){
  return "index";
}

springmvc(5)https://developer.aliyun.com/article/1530460

相关文章
|
9月前
|
JSON JavaScript 前端开发
|
9月前
|
Java Spring
|
9月前
|
XML JSON fastjson
|
9月前
|
前端开发 Java 数据处理
|
15天前
|
前端开发 Java 数据格式
|
15天前
|
前端开发 Java 应用服务中间件
|
15天前
|
JSON 前端开发 JavaScript
|
23天前
|
存储 JSON 前端开发
|
9月前
|
JSON 前端开发 Java
springMVC(2)
SpringMVC_JSR303数据校验
35 0
|
10月前
|
前端开发 Java Spring
你真的了解SpringMVC吗?(下)
你真的了解SpringMVC吗?(下)
46 0

热门文章

最新文章