spring入门之MVC

web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<!--配置编码过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:bean.xml</param-value>
    </context-param>
<!--配置DispatcherServlet-->
    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-web.xml</param-value>
        </init-param>
        <!--值为0或正数整时,servlet随容器启动而创建
         值为负数整时,servlet随容器启动而创建-->
            
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

spring-web.xml配置

location元素表示webapp目录下的static包下的所有文件;

mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b;

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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">
<!--&lt;!&ndash;配置映射器RequestMappingHandlerMapping&ndash;&gt;-->
<!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>-->
<!--&lt;!&ndash;配置适配器&ndash;&gt;-->
<!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>-->
<!--使用mvc驱动进行配置适配器和映射器,这样做可以使用mvc的@DateTimeFormat和@NumberFormat来处理400的参数绑定失败错误-->
    <mvc:annotation-driven></mvc:annotation-driven>
<!--    对于静态的资源,配置后将不经过dispatcherServlet管理,配置mapper映射关系,mapper为在请求的路径,location为对该请求配置对应的本地路径-->
    <mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
    <mvc:resources mapping="/font/**" location="/font/"></mvc:resources>
    <!--配置视图器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    <context:component-scan base-package="com.hn"></context:component-scan>
</beans>

spring-datasource.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       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">

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;setCharacterEncoding=utf-8"></property>
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
</bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath*:mapper/*.xml" />
        <property name="plugins">
        <array>
            <bean class="com.github.pagehelper.PageInterceptor">
                <property name="properties">
                    <value>
                        helperDialect=mysql
                        reasonable=true
                        supportMethodsArguments=true
                        params=count=countSql
                        autoRuntimeDialect=true
                    </value>
                </property>
            </bean>
        </array>
        </property>
    </bean>
<!--将mapper的实现类放入springIOC中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.hn.mapper" />
    </bean>
</beans>

beans.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       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">

    <import resource="classpath*:data-source.xml"></import>
</beans>

jsp的时间格式化

<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  <fmt:formatDate value="${user.date}" pattern="yyyy/MM/dd HH:mm:ss"></fmt:formatDate>

打印输出

<input type="date"  name="date" value="<fmt:formatDate value='${user.date}' pattern='yyyy-MM-dd'></fmt:formatDate>">

增删改查

进行修改操作表单的ajax

<script>
$(function(){
    $("form").submit(function (){

        $.ajax({
            type:"post",
            data:id=$.param({id:${user.id}})+'&'+$("form").serialize(),
            url:'${pageContext.request.contextPath}/user/update',
            success:function(){
                $("#alarm").show();
                setTimeout("location.href='${pageContext.request.contextPath}/user/list'",1000);
            }
        })
        return false;
    })

})
</script>

controller的基本使用

controller方法的使用

1.@RequestMapping(value=“user”),创建请求映射。method设置约束接收的请求方式

2.@RequestParam使用在参数上,用于跟请求的数据名进行绑定,参数名称自定义配置,可定义默认值

3.@PathVariable使用/{}来传递get请求

4.ModelAndView的传递参数,可以在方法中增加Model的参数,来返回String替代ModelAndView.

5.拿到cookie的值 public ModelAndView cookie(@CookieValue(“JSESSIONID”)String value)

6.地址的请求转发和重定向

使用forward:,redirect:前缀后InternalResourceViewResolver的前缀和后缀将失效

forward:请求转发地址默认以配置的视图器为基准

redirect:重定向地址默认以相对路径为基准

都可以使用/来绝对工程路径

7.因为请求传递过来的数据实际上是字符串,因此要对请求传递过来的一些参数进行格式化

http常见响应码

200 请求成功

500 代码错误

400 Bad request 一般是数据类型无法绑定所造成的

405 拒绝请求类型,比如@RequestMapping设置的请求方式约束

controller代码实现

@Controller
@RequestMapping("user")
public class UserController {
    @Autowired
    private IUserService userService;

    @RequestMapping("/list")
    public ModelAndView list(@RequestParam(value = "page", defaultValue = "1") int page) {

        ModelAndView mav = new ModelAndView();
        mav.setViewName( "user/list" );
        Page<User> pageUser = (Page<User>) userService.list( page, 4 );
        mav.addObject( "users", pageUser );
        return mav;
    }

    @RequestMapping("/add")
    public String goAdd() {
        return "user/add";
    }

    @RequestMapping("/doAdd")
    public String add(User user) {
        userService.addUser( user );
        return "redirect:/";
    }

    @RequestMapping("/to_update/{uid}")
    public ModelAndView toUpdate(@PathVariable("uid")int uid) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName( "user/to_update" );

        modelAndView.addObject( "user", userService.getUserById( uid ) );
        return modelAndView;
    }
日期类型参数绑定

方式一:实体类属性加@DateTimeFormat(pattern = “yyyy-MM-dd”)

方式二:在controller层创建@InitBinder对获取指定的数据参数名进行处理。

@InitBinder
public void initDate(WebDataBinder dataBinder){
dataBinder.addCustomFormatter( new DateFormatter("yyyy-MM-dd"),"date" );
}

方式三:自定义spring参数处理器、

自定义注解

@Target( ElementType.PARAMETER )
@Retention(RetentionPolicy.RUNTIME)
public @interface MyDate {
    String[] params() default "";
    String pattern() default "yyyy-MM-dd";
}

实现自定义参数解析器

public class MyHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver{
    private String[] params;  /*属性*/
    private String pattern;   /*日期的格式*/
    //表单中传入birthday参数到controller的参数User的birthday,如何转换
    @Override
    public Object resolveArgument(MethodParameter methodParam, ModelAndViewContainer arg1, NativeWebRequest webRequest,
            WebDataBinderFactory arg3) throws Exception {
      //1.获取controller方法参数Users user的类型对象
        Object object = BeanUtils.instantiateClass(methodParam.getParameterType());
        //2.获取参数类型对象的类信息(Users类的属性和方法)
        BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
        //3.获取请求对象Request
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
         //4.获取Users类类型对象的所有属性描述(获取Users类的所有属性)
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            //5.得到每个属性的名字(Users类的属性名),并根据属性名称得到请求参数的值
            String value = request.getParameter(propertyDescriptor.getName());
            //6.判断非空
            if (!StringUtils.isEmpty(value)) {
                //5.得到属性的set方法
                Method writeMethod = propertyDescriptor.getWriteMethod();
                //6.如果set方法为非公有方法,暴力破解
                if (!Modifier.isPublic(writeMethod.getModifiers())) {
                    writeMethod.setAccessible(true);
                }
                //7.判断属性名是否为Date指定的params值,如果是params指定值 则进行日期转换
                if (propertyDescriptor.getName().equals(params[0])) {//日期属性
                    SimpleDateFormat sdf = new SimpleDateFormat(this.pattern);
                    java.util.Date date = sdf.parse(value);
                    //调用setBirthday(date)
                    writeMethod.invoke(object, date);
                } else {//非日期的属性
                    //属性类型为Integer
                    if(propertyDescriptor.getPropertyType().equals(Integer.class)) {
                        writeMethod.invoke(object, Integer.parseInt(value));
                     //属性类型为字符串
                    }else {
                        writeMethod.invoke(object, value);
                    }
                }
            }
        }
        return object;
    }


    //哪些参数才需要调用我们上面的解析方法进行解析
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        //1、判断controller方法上是否有MyDate注解
        boolean hasParameterAnnotation = parameter.hasParameterAnnotation(MyDate.class);
        if (!hasParameterAnnotation) {
            //不会进入下面的resolveArgument方法进行参数的解析
            return false;
        }
        //2、获取Date注解对象
        MyDate parameterAnnotations = parameter.getParameterAnnotation(MyDate.class);
        //3、获取Date注解的params参数
        String[] parameters = parameterAnnotations.params();
        if (!StringUtils.isEmpty(parameters)) {
            params = parameters;
            //4.获取Date注解的pattern参数
            pattern = parameterAnnotations.pattern();
          //进入下面的resolveArgument方法进行参数的解析
            return true;
        }
        return false;
    }

}

spring-web.xml配置

<mvc:annotation-driven>
    <mvc:argument-resolvers>
        <bean class="com.hn.annotation.MyHandlerMethodArgumentResolver"></bean>
    </mvc:argument-resolvers>
</mvc:annotation-driven>

然后再参数上使用注解即可

@RequestMapping("/doAdd")
public String add(@MyDate(params = "date") User user) {
    userService.addUser( user );
    return "redirect:/";
}
通过request获取服务器相对路径及绝对路径

String scheme = request.getScheme();//http

String serverName = request.getServerName();//localhost

int port = request.getServerPort();//8080

String context = request.getContextPath();// /demo(项目名称);

String path = scheme+"😕/"+serverName+":"+port+context+"/" // http://localhost:8080/demo/

获取上传文件保存服务器的路径

String filePath = request.getSession().getServletContext().getRealPath(“uploadFiles/pictures”);

C:\Program Files (x86)\apache-tomcat-7.0\uploadFiles\pictures

统一异常处理

1.实现org.springframework.web.servlet.HandlerExceptionResolver接口,缺点只能返回ModelAndView,实际情况都使用json,因此,此方法实际作用很低。

@component
public class ExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
//        System.out.println(o);
        e.printStackTrace();

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName( "404" );
        modelAndView.addObject( "msg",e.getMessage() );
        return modelAndView;
    }
}

2.注解声明

package com.hn.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice//控制层增强
public class AnnotationExceptionHandle {
    @ExceptionHandler(Exception.class)//选定该异常的处理方式
    @ResponseBody
    public String exceptionHandler(Exception e) {
        e.printStackTrace();
        return "";
    }
}

MD5加密

需要依赖

org.apache.commons.lang3.StringUtils

package com.hn.utils;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
public class PropertiesUtil {

//    private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);

    private static Properties props;

    static {
        String fileName = "ndcrm.properties";
        props = new Properties();
        try {
            props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8"));
        } catch (IOException e) {
//            logger.error("配置文件读取异常",e);
        }
    }

    public static String getProperty(String key){
        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
            return null;
        }
        return value.trim();
    }

    public static String getProperty(String key,String defaultValue){

        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
            value = defaultValue;
        }
        return value.trim();
    }
    public static void main(String[] args) {
        System.out.println(PropertiesUtil.getProperty("password.salt"));
    }
}
package com.hn.utils;
import java.security.MessageDigest;

public class MD5Util {

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append( byteToHexString( b[i] ) );

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    /**
     * 返回大写MD5
     *
     * @param origin
     * @param charsetname
     * @return
     */
    private static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String( origin );
            MessageDigest md = MessageDigest.getInstance( "MD5" );
            if (charsetname == null || "".equals( charsetname ))
                resultString = byteArrayToHexString( md.digest( resultString.getBytes() ) );
            else
                resultString = byteArrayToHexString( md.digest( resultString.getBytes( charsetname ) ) );
        } catch (Exception exception) {
        }
        return resultString.toUpperCase();
    }

    public static String MD5EncodeUtf8(String origin) {
        origin = origin + PropertiesUtil.getProperty( "password.salt", "" );
        return MD5Encode( origin, "utf-8" );
    }


    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static void main(String[] args) {
        System.out.println( MD5EncodeUtf8( "admin" ) );
    }
}

ndcrm.properties文件配置盐

password.salt=hhh@@!!!ld

拦截器

通常流程:

过滤器->dispatcherServlet->RequestMappingHandlerMapping->RequestMappingHandlerAdapter->拦截器->controller

public class LoginInterceptor implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(handler);
        HttpSession session = request.getSession();
        if ( session.getAttribute( "userType")!=null){
            return true;
        }
        response.sendRedirect( "/login" );
        return false;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
       
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

xml配置,配置在前面的拦截器会先拦截

<mvc:interceptors>
    <mvc:interceptor >
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/login"/>
        <mvc:exclude-mapping path="/user/do_login"/>
        <bean class="com.hn.interceptor.LoginInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

拦截器分为在访问控制层前,控制层返回前,控制层后。值得注意的事情是两个拦截的情况,设为A、B,A在前。

情况一:A的pre放行,B拦截,最终A还会执行A的after。

情况二:A,B均拦截,顺序为A-pre->B->pre->B-post->A-post->B-after->A-after

定时任务

需要依赖

在这里插入图片描述

有xml和注解配置两种

xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        ">
<!--    配置类-->
    <bean id="task" class="com.cc.timer.XMLSchedule"></bean>

    <!--    配置类中指定的方法为定时任务-->
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="task"/>
        <property name="targetMethod" value="t"/>
    </bean>
<!--    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">-->
<!--        &lt;!&ndash; see the example of method invoking job above &ndash;&gt;-->
<!--        <property name="jobDetail" ref="jobDetail"/>-->
<!--        &lt;!&ndash; 10 seconds &ndash;&gt;-->
<!--&lt;!&ndash;        <property name="startDelay" value="10000"/>&ndash;&gt;-->

<!--&lt;!&ndash;        <property name="repeatInterval" value="50000"/>&ndash;&gt;-->
<!--    </bean>-->
<!--使用cron表达式对任务进行配置-->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetail"/>
        <!-- run every morning at 6 AM -->
        <property name="cronExpression" value="0/1 * * * * ?"/>
    </bean>
<!--    在任务工厂中添加任务-->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="cronTrigger"/>
            </list>
        </property>
    </bean>
</beans>

可以看得出来xml配置很繁琐,建议使用注解

@Component
@EnableScheduling
public class AnnotationSchedule {
   
    @Scheduled(cron = "0/1 * * * * ? ")
    public void t() throws InterruptedException{
        System.out.println("1");
    }
}

异步支持

@Component
@EnableAsync
@EnableScheduling
public class AnnotationSchedule {
    @Async
    @Scheduled(cron = "0/1 * * * * ? ")
    public void t() throws InterruptedException{
        System.out.println("1");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值