spring通知、mvc拦截器、异常管理、quartz定时器、mvc.xml的配置、mvc上传下载和json、特定的注解驱动

本文介绍了如何在Spring MVC应用中集成Quartz定时任务,包括注解方式和继承方式的实现,并详细讲解了AOP拦截器、异常管理及Controller配置。同时涵盖了MVC拦截器和自定义序列化技术的应用。
摘要由CSDN通过智能技术生成
public class MyThread implements ThrowsAdvice {

    public void afterThrowing(Exception ex){

        System.out.println("出异常了");

    }

}
public class MyAfter implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("后置日志");

    }
}
public class MyInteceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("环绕前置通知");
        //放行
        invocation.proceed();
        System.out.println("环绕后置通知");
        return null;
    }
}
@Aspect
@Component
public class Log {
    //定义切入点
    @Pointcut("execution(* service.impl.UserServiceImpl.*(..))")
    public void a(){}

    @Before("a()")
    public void before(JoinPoint joinPoint){

        System.out.println("注解前置通知");
    }
    @AfterReturning(value = "a()",returning = "obj")
    public void after(JoinPoint joinpoint,Object obj){

        System.out.println("注解后置通知");

    }
    //异常通知
    @AfterThrowing(value = "a()",throwing = "ex")
    public void thr(JoinPoint joinPoint,Exception ex){

        System.out.println("异常通知");
    }
    //环绕通知
    @Around(value = "a()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("环绕前置");
        //放行
        Object proceed = joinPoint.proceed();
        System.out.println("环绕后置");
        return proceed;
    }

}
<!--环绕-->
<beans>
    <bean id="inter" class="MyInteceptor"/>
    <!--后置-->
    <bean id="myAfter" class="MyAfter"/>
    <!--异常通知-->
    <bean id="myThrow" class="MyThread"/>
    <aop:config>
        <aop:pointcut id="point" expression="execution(* service.impl.UserServiceImpl.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="inter" pointcut-ref="point"></aop:advisor>
        <aop:advisor advice-ref="myAfter" pointcut-ref="point"/>
        <aop:advisor advice-ref="myThrow" pointcut-ref="point"/>
    </aop:config>
    
    <bean id="log" class="entity.Log"></bean>
    <!--设置注解自动加入通知-->
    <aop:aspectj-autoproxy/>
</beans>

mvc拦截器

public class inter implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("pre");
        Object login = request.getSession().getAttribute("login");
        if (login!=null){
            //放行
            return true;
        }

        //跳转到登录界面
        response.sendRedirect(request.getContextPath()+"/login.jsp");
        //不放行
        return false;
    }

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

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }



}
<!--定义拦截器的配置 类需要实现接口implements HandlerInterceptor-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--<mvc:mapping path="/inter/test1"/>-->
            <!--<mvc:mapping path="/mvc/**"/>-->
            <mvc:mapping path="/h1"/> <!-- test开头 -->
            <!--<mvc:mapping path="/**"/> &lt;!&ndash; /** 任意多级任意路径 &ndash;&gt;-->
            <mvc:exclude-mapping path="/login.jsp"/>   <!--不拦截此路径-->
            <bean class="com.lee.inter"></bean>   <!--拦截器类-->
        </mvc:interceptor>
    </mvc:interceptors>

异常管理

/**
 * 异常解析器处理所有异常
 * 配置文件交由spring管理
 */
public class MyException implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView=new ModelAndView();
        //跳转到页面
        if (e instanceof ArithmeticException){
            modelAndView.setViewName("error1");
        }else if (e instanceof IOException){
            modelAndView.setViewName("error2");
        }else {
            modelAndView.setViewName("hello");
        }
        return modelAndView;
    }
}
<!--定义异常处理的bean 类需要实现接口implements HandlerExceptionResolver-->
    <bean class="com.lee.MyException"></bean>

mvc配置拦截器和异常处理以及controller的配置,mvc的使用需要在web.xml文件中配置前端控制器

<beans 	xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mvc="http://www.springframework.org/schema/mvc"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
							http://www.springframework.org/schema/beans/spring-beans.xsd
							http://www.springframework.org/schema/context
							http://www.springframework.org/schema/context/spring-context.xsd
							http://www.springframework.org/schema/mvc
							http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 告知springmvc  哪些包中 存在 被注解的类  扫描注解-->
    <context:component-scan base-package="com.lee.controller"></context:component-scan>
    <!--静态资源过滤 不加这个静态资源会被过滤掉-->
    <mvc:default-servlet-handler/>
    <!-- 注册注解开发驱动 特定注解需要驱动 -->
    <mvc:annotation-driven>
        <!-- 安装FastJson,转换器 -->
        <!--<mvc:message-converters>-->
            <!--<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">-->
                <!--<property name="supportedMediaTypes">-->
                    <!--<list>-->
                        <!--<value>application/json</value>-->
                    <!--</list>-->
                <!--</property>-->
            <!--</bean>-->
        <!--</mvc:message-converters>-->
    </mvc:annotation-driven>
    <!-- 视图解析器
         作用:1.捕获后端控制器的返回值="index"
              2.解析: 在返回值的前后 拼接 ==> "/index.jsp"
     -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 -->
        <!--<property name="prefix" value="/WEB-INF/jsp/"></property>-->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"></property>
    </bean>
    
<!--定义异常处理的bean 类需要实现接口implements HandlerExceptionResolver-->
    <bean class="com.lee.MyException"></bean>
    
<!--定义拦截器的配置 类需要实现接口implements HandlerInterceptor-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--<mvc:mapping path="/inter/test1"/>-->
            <!--<mvc:mapping path="/mvc/**"/>-->
            <mvc:mapping path="/h1"/> <!-- test开头 -->
            <!--<mvc:mapping path="/**"/> &lt;!&ndash; /** 任意多级任意路径 &ndash;&gt;-->
            <mvc:exclude-mapping path="/login.jsp"/>   <!--不拦截此路径-->
            <bean class="com.lee.inter"></bean>   <!--拦截器类-->
        </mvc:interceptor>
    </mvc:interceptors>

    <!-- 上传解析器
	    -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="1048576"/>
    </bean>
</beans>

quartz定时器两种方式
注解方式

<!--扫描包-->
    <context:component-scan base-package="com.lee"/>
    <!--特定注解驱动-->
    <task:annotation-driven/>
@Component
public class myjob  {
//秒 分 时 日 月 星期 必须有一个问号?,一般写六位即可 
@Scheduled(cron = "* * * * * ?")
    public void m1(){
        System.out.println("敲代码"+new Date());
    }
       @Scheduled(cron = "5,15,25,30 * * * * ?")
    public void m2(){

        System.out.println("-------------------------");
    }

}

quartz方式二 继承

public class myjob2 implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("敲代码了嘛????");
    }
}
<!--工作-->
    <bean id="jobDetailFactoryBean" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="name" value="j1"/>
        <property name="group" value="g1"/>
        <property name="jobClass" value="com.lee.myjob2"/>
    </bean>
    <!--触发器-->
    <bean id="triggerFactoryBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="name" value="t1"/>
        <property name="group" value="g1"/>
        <property name="cronExpression" value="* * * * * ?"/>
        <property name="jobDetail" ref="jobDetailFactoryBean"/>
    </bean>
    <!--scheduler-->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="triggerFactoryBean"/>
            </list>
        </property>
    </bean>

上传 需要pom、上传解析器
<!-- 上传解析器
id必须是:“multipartResolver” -->
<bean id=“multipartResolver”
class=“org.springframework.web.multipart.commons.CommonsMultipartResolver”>
<!-- 最大可上传的文件大小 单位:byte 超出后会抛MaxUploadSizeExceededException异常,可以异常解析器捕获 -->
</property</bean>

@RequestMapping("/test1")
public String hello1(String username,MultipartFile source,HttpSession session) {
    //文件的原始名称
    String filename = source.getOriginalFilename();
    //定制全局唯一的命名
    String unique = UUID.randomUUID().toString();
    //获得文件的后缀
    String ext = FilenameUtils.getExtension(filename);//abc.txt   txt    hello.html  html
    //定制全局唯一的文件名
    String uniqueFileName = unique+"."+ext;
    System.out.println("唯一的文件名:"+uniqueFileName);

    //文件的类型
    String type = source.getContentType();
    System.out.println("filename:"+filename+" type:"+type);

    //获得 upload_file的磁盘路径 ==> 在webapp目录下创建一个目录"upload_file",且此目录初始不要为空,否则编译时被忽略
    String real_path = session.getServletContext().getRealPath("/upload_file");
    System.out.println("real_path:"+real_path);

    //将上传的文件,存入磁盘路径中
    //source.transferTo(new File("d:/xxxx/xxxx/xx.jpg"))
    source.transferTo(new File(real_path+"\\"+uniqueFileName));
    return "index";
}

下载

@RequestMapping("/test1")
public void hello1(String name,HttpSession session,HttpServletResponse response){
    System.out.println("name:"+name);
    //获得要下载文件的绝对路径
    String path = session.getServletContext().getRealPath("/upload_file");
    //文件的完整路径
    String real_path = path+"\\"+name;

    //设置响应头  告知浏览器,要以附件的形式保存内容   filename=浏览器显示的下载文件名
    response.setHeader("content-disposition","attachment;filename="+name);

    //读取目标文件,写出给客户端
    IOUtils.copy(new FileInputStream(real_path), response.getOutputStream());

    //上一步,已经是响应了,所以此handler直接是void
}

fastjson

  • 日期格式化:@JSONField(format=“yyyy/MM/dd”)
  • 属性名修改:@JSONField(name=“birth”)
  • 忽略属性:@JSONField(serialize = false)
  • 包含null值:@JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue) 默认会忽略所有null值,有此注解会输出null
    • @JSONField(serialzeFeatures = SerializerFeature.WriteNullStringAsEmpty) null的String输出为""
  • 自定义序列化:@JSONField(serializeUsing = MySerializer2.class)
public class User implements Serializable{
	@JSONField(serialize = false)
    private Integer id;
    @JSONField(name="NAME",serialzeFeatures = SerializerFeature.WriteNullStringAsEmpty)
	private String name;
    @JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue) 
    private String city;
	@JSONField(format="yyyy/MM/dd")
	private Date birth;
    @JSONField(serializeUsing = MySerializer2.class)
    private Double salary;
	...
}
public class MySerializer2 implements ObjectSerializer {
    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
                      int features) throws IOException {
        Double value = (Double) object; // salary属性值
        String text = value + "元";// 在salary后拼接 “元”
        serializer.write(text); // 输出拼接后的内容
    }
}
new User(1,null,null,new Date()100.5);
// 如上对象,转换json:
{NAME:"",city:null,"birth":"2020/12/12""salary":"100.5元"}

jackjson

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
	private Date birth;
	@JsonProperty("new_id") //不再使用原属性名,而是 "new_id"
    private Integer id;
      @JsonIgnore // 生成json时,忽略此属性
	private String name;
	 @JsonInclude(JsonInclude.Include.NON_NULL) // 若"name==null" 忽略此属性
	private String name;
    @JsonInclude(value= JsonInclude.Include.NON_EMPTY)  // 若hobby长度为0或==null 忽略此属性
    private List<String> hobby;
 

自定义序列化jackjson

   @JsonSerialize(using = MySerializer.class) // 使用MySerializer输出某属性
    public class User {
    private Integer id;
    private String name;
    @JsonSerialize(using = MySerializer.class)
    private Double salary = 10000.126;//在输出此属性时,使用MySerializer输出
    ....
    get/set
}
则输出json时:{"id":xx,"name":"xxx","salary":10000.13}
public class MySerializer extends JsonSerializer<Double> {

    // value即 Double salary的值
    @Override 
    public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // 将Double salary的值 四舍五入
        String number = BigDecimal.valueOf(value).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        // 输出 四舍五入后的值
        gen.writeNumber(number);
    }
}

特定的注解驱动

<!--特定注解驱动controller-->
    <mvc:annotation-driven/>
    <!--特定注解驱动 定时器-->
    <task:annotation-driven/>
    <!--特定注解驱动 事务-->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值