victory的博客

长安一片月,万户捣衣声

0%

处理响应数据 ModelAndView

处理请求数据
项目的ParamController.java的类中加入以下代码:

/**
 * SpringMVC处理请求过程中,往作用域中放值有以下三种方式
 * 总结:根据ModelAndView源码调试,不管使用以下那种方式,最终都会把model数据和view数据封装到一个ModelAndView中
 */
//往作用域中放值方式1
//    @RequestMapping(value="/param", method=RequestMethod.POST)
//    public ModelAndView param(){
//        ModelAndView mav = new ModelAndView();
//        //javaWEB: request.setAttribute(xxx) 
//        mav.addObject("username", "root");//往request作用域中放值
//        mav.setViewName("success");//设置视图名称,实现页面跳转
//        return mav;
//    }
    
    //往作用域中放值方式2
//    @RequestMapping(value="/param", method=RequestMethod.POST)
//    public String param(Map<String, Object> map){
//        map.put("username", "admin");//向作用域中放值
//        return "success";//返回视图名称
//    }

//往作用域中放值方式3
@RequestMapping(value="/param", method=RequestMethod.POST)
public String param(Model model){
    model.addAttribute("usernaem", "zhangsan");//向作用域中放值
    return "success";//返回视图名称
}

并在param.jsp页面获取request作用域中的值

<!-- ${requestScope.username } -->
    ${username}

REST风格 GET/POST/PUT/DELETE请求

*REST:即 Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。

浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不
支持,Spring3.0 添加了一个过滤器(HiddenHttpMethodFilter),可以将这些
请求转换为标准的 http 方法
,使得支持 GET、POST、PUT 与 DELETE 请求。

HiddenHttpMethodFilter支持REST风格的过滤器:可以将POST请求转换为PUT或DELETE请求

阅读全文 »

SpringMVC之HelloWorld

springMVC的搭建过程:

1.导入jar

2.在web.xml配置springMVC的核心(前端)控制器DispatcherServlet
作用:加载springMVC的配置文件,在下方的配置方式下,DispatcherServlet
自动加载配置文件,此时的配置文件有默认的位置和名称
默认位置:WEB-INF下,默认名称:-servlet.xml,
例如以下配置方式的文件名:springMVC-servlet.xml
当加载了配置文件,springMVC就会根据扫描组件找到控制层

<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

3.创建一个POJO,在此类上加上@Controller注解,springMVC就会将此类作为控制层加载,让其处理请求响应
4.在控制层中,需要在方法上设置@RequestMapping(value=”hello”),
springMVC就是通过此注解将请求路径与控制层中的方法进行匹配,此时请求路径为localhost:8080/projectName/xxx
5.处理请求的方法会返回一个字符串,即视图名称,最终会通过配置文件中配置的视图解析器实现页面跳转
方式:prefix + 视图名称 + suffix,此为最终跳转的页面路径

阅读全文 »

JdbcTemplate增删改查

1.项目目录

2.Emp.java

package com.atguigu.jdbctemplate;

public class Emp {
    private Integer eid;
    private String ename;
    private Integer age;
    private String sex;
    public Integer getEid() {
        return eid;
    }
    public void setEid(Integer eid) {
        this.eid = eid;
    }
    public String getEname() {
        return ename;
    }
    public void setEname(String ename) {
        this.ename = ename;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "Emp [eid=" + eid + ", ename=" + ename + ", age=" + age + ", sex=" + sex + "]";
    }
    
}

3.ssm表

4.db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=root

5.jdbc.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-4.0.xsd">
    
    <!-- 引入属性文件 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="db.properties"></property>
    </bean>
    
    <!-- 引入属性文件 -->
    <context:property-placeholder location="db.properties"/>
    
    <!-- 创建数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    
    <!-- 通过数据源配置JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
</beans>

6.TestJdbcTemplate.java

package com.atguigu.jdbctemplate;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

public class TestJdbcTemplate {
    ApplicationContext ac = new ClassPathXmlApplicationContext("jdbc.xml");
    JdbcTemplate jdbcTemplate = ac.getBean("jdbcTemplate", JdbcTemplate.class);
    
    @Test
    public void test() {
        //单个增删改
        //System.out.println(jdbcTemplate);//org.springframework.jdbc.core.JdbcTemplate@6483f5ae
        //jdbcTemplate.update("insert into emp values(1,'zhangsan',23,'男')");
        
        //增加记录
        //String sql = "insert into emp values(2, ?, ?, ?)";
        //jdbcTemplate.update(sql, "lisi", 25, "男");
        
        //删除记录
        //String sql = "delete from emp where eid=?";
        //jdbcTemplate.update(sql,2);
        
        //修改记录
        //String sql = "update emp set ename=? where eid=?"; 
        //jdbcTemplate.update(sql, "lisi", 1);
        
        //不能使用
        //String sql = "delete from emp where eid in (?)";
        //String eids = "3, 4, 5";
        //jdbcTemplate.update(sql,eids);
        
        //可以使用
        //String eids = "3,4,5";
        //String sql = "delete from emp where eid in ("+eids+")";
        //jdbcTemplate.update(sql);
        
        //String sql = "select * from emp where ename like '%?%'";//不能使用
        //String sql = "select * from emp where ename like concat('%',?,'%')";//可以使用
    }
    
    @Test
    public void testBatchUpdate(){
        //批量增删改
//        String sql = "insert into emp values(?,?,?,?)";
//        List<Object[]> list = new ArrayList<>();
//        list.add(new Object[]{3,"a1",1,"男"});
//        list.add(new Object[]{4,"a2",2,"男"});
//        list.add(new Object[]{5,"a3",3,"男"});
//        jdbcTemplate.batchUpdate(sql, list);
    }
    
    @Test
    public void testQueryForObject(){
        //jdbcTemplate.queryForObject(sql, requiredType);//用来获取单个的值
        //jdbcTemplate.queryForObject(sql, rowMapper);//用来获取单条数据
        
//        String sql= "select eid,ename,age,sex from emp where eid=?";
//        RowMapper<Emp> rowMapper = new BeanPropertyRowMapper<>(Emp.class);//将列名(字段名或字段名的别名)与属性名进行映射
//        Emp emp = jdbcTemplate.queryForObject(sql, new Object[]{3}, rowMapper);
//        System.out.println(emp);
        
        String sql = "select count(*) from emp";
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
        System.out.println(count);
    }
    
    @Test
    public void testQuery(){
        String sql = "select eid,ename,age,sex from emp";
        RowMapper<Emp> rowMapper = new BeanPropertyRowMapper<>(Emp.class);
        List<Emp> list = jdbcTemplate.query(sql, rowMapper);
        for(Emp emp:list){
            System.out.println(emp);
        }
    }

}

以XML方式配置切面

1.项目目录

2.MathI.java(接口)

package com.atguigu.spring.aopxml;

public interface MathI {
    int add(int i, int j);
    int sub(int i, int j);
    int mul(int i, int j);
    int div(int i, int j);
}

3.MathImpl.java(实现类)

package com.atguigu.spring.aopxml;

import org.springframework.stereotype.Component;

@Component
public class MathImpl implements MathI{

    @Override
    public int add(int i, int j) {
        int result = i + j;
        return result;
    }
    
    @Override
    public int sub(int i, int j) {
        int result = i - j;
        return result;
    }

    @Override
    public int mul(int i, int j) {
        int result = i * j;
        return result; 
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        return result;
    }
}

4.MyLogger.java(切面)

package com.atguigu.spring.aopxml;

import org.springframework.stereotype.Component;

@Component
public class MyLogger {
    public void before(){
        System.out.println("前置通知");
    }
}

5.aop-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:aop="http://www.springframework.org/schema/aop"
    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-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

    <context:component-scan base-package="com.atguigu.spring.aopxml"></context:component-scan>
    
    <!-- 以XML方式配置切面  -->
    <aop:config>
        <!-- 切面 -->
        <aop:aspect ref="myLogger">
            <!-- 前置通知 通知通过切入点表达式作用于连接点-->
            <!-- <aop:before method="before" pointcut="execution(* com.atguigu.spring.aopxml.*.*(..))"/> -->
            
            <aop:pointcut expression="execution(* com.atguigu.spring.aopxml.*.*(..))" id="cut"/>
            <aop:before method="before" pointcut-ref="cut"/>
        </aop:aspect>
    </aop:config>
</beans>

6.Test.java(测试类)

package com.atguigu.spring.aopxml;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("aop-xml.xml");
        MathI math = ac.getBean("mathImpl", MathI.class);
        int add = math.add(2, 2);
        System.out.println(add);
    }

}

7.运行结果

前置通知
4

动态代理-数学计算器

项目目录

1.要求
1)计算器能够执行加减乘除运算
2)日志:在程序执行期间追踪正在发生的活动
3)验证:希望计算器只能处理正数的运算

2.常规实现

**MathI.java**
package com.atguigu.proxy;

public interface MathI {
    int add(int i, int j);
    int sub(int i, int j);
    int mul(int i, int j);
    int div(int i, int j);
}

MathImpl.java

package com.atguigu.proxy;

public class MathImpl implements MathI{

    @Override
    public int add(int i, int j) {
        System.out.println("method:add,arguments:" + i + "," + j);
        System.out.println("method:add,results:" + (i + j));
        return i + j;
    }
    
    @Override
    public int sub(int i, int j) {
        System.out.println("method:sub,arguments:" + i + "," + j);
        System.out.println("method:sub,results:" + (i - j));
        return i - j;
    }

    @Override
    public int mul(int i, int j) {
        System.out.println("method:mul,arguments:" + i + "," + j);
        System.out.println("method:mul,results:" + (i * j));
        return i * j;
    }

    @Override
    public int div(int i, int j) {
        System.out.println("method:div,arguments:" + i + "," + j);
        System.out.println("method:div,results:" + (i / j));
        return i / j;
    }
}

常规实现方法存在的问题
①代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀。每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点。
②代码分散: 以日志需求为例,只是为了满足这个单一需求,就不得不在多个模块(方法)里多次重复相同的日志代码。如果日志需求发生变化,必须修改所有模块。

3.动态代理
MathI.java(与2中的代码相同)

MathImpl.java(2中的代码中去掉日志信息)

MyLogger.java(日志类)

ProxyUtil.java(代理类)

package com.atguigu.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class ProxyUtil{
    //代理模式:1、静态代理(代理对象真实存在,是自己写好的) 2、动态代理(动态生成代理对象,不需要自己写)
    private MathImpl mathImpl;//目标对象 目标对象类必须实现接口
    
    public ProxyUtil(MathImpl mathImpl) {
        super();
        this.mathImpl = mathImpl;
    }

    public Object getProxy(){
        //获取当前类的类加载器用来加载代理对象所属类
        ClassLoader loader = this.getClass().getClassLoader();//动态生成代理对象就需要动态代理类,代理类的执行需要类加载器
        //获取目标对象实现的所有接口的Class,代理类会和目标对象实现相同的接口,最终通过代理对象实现功能
        Class[] interfaces = mathImpl.getClass().getInterfaces();
        
        return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler(){

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //代理对象实现功能的方式
                try{
                    MyLogger.before(method.getName(), Arrays.toString(args));
                    Object result = method.invoke(mathImpl, args);//动态代理对象实现功能(调用目标对象的方法)
                    MyLogger.after(method.getName(), result);
                    return result;
                }catch (Exception e){
                    MyLogger.throwing();
                    e.printStackTrace();
                }finally{
                    System.out.println("哪都有我");
                }
                return null;
                
            }
        });
    }
}

Test.java(测试类)

package com.atguigu.proxy;

public class Test {

    public static void main(String[] args) {
//        MathI math = new MathImpl();
//        int result = math.add(1, 1);
//        System.out.println(result);
        ProxyUtil proxy = new ProxyUtil(new MathImpl());
        
        MathI math = (MathI)proxy.getProxy();
        
        int i = math.add(1, 1);
        System.out.println(i);
        
        int j = math.div(4, 0);
        System.out.println(j);
    }
}