public String delete(@RequestParam(value="ideaNum", required=false) String[] nums, ModelMap model, HttpServletRequest request) {

...

}


삭제 시 여러 idx 값을 배열로 담아 처리

JSP/Servlet redirect, forward(서블릿 리다이렉트, 포워드) 



1. Redirect

 

Redirection인 경우 클라이언트에서 서버로 요청을 보내면 클라이언트 요청을 처리 후 리다이렉트 메소드가 호출되면 Client 브라우저에 응답을 보내며 이 응답에는 브라우저가 웹 컨테이너의 응답을 받은 후  location 에 새롭게 Redirection 될곳의 주소를 넣어서 보낸다.


여기에서 하나의 요청이 종결되고, 새로부여받은 URL로 Client 브라우저에서 새롭게 요청하기 때문에 이전 요청 스코프에 저장되어 있던 request 객체는 소멸된다.


클라이언트 브라우저 상단의 URL 창에도 새로운 요청이 만들어져 넘어가므로 리다이렉션되는 곳으로 URL 주소가 바뀐다.


요청객체를 지우고 다시 만드므로 시간이 소요됨.



2. Forward

 

요청이 포워딩 될때는 해당 요청이 서버의 다른자원(서블릿, JSP)에 전달된다.(Request 객체 재활용), 이때 이 요청을 처리하는것을 클라이언트(브라우저)에게 알리지 않고, 이런방식의 처리는 웹 컨테이너 내부에서만 일어나므로 클라이언트는 알수없게 된다.


서블릿컨테이너에서 이를 해석하여,  즉 컨테이너 안에서 해석을 한다는 의미. 그래서 forward한 곳으로 자원을 이용하여 응답을 만들어 보내게 된다.


클라이언트는 이 사실(포워드된 사실)을 전혀 알지 못하고 그래서 URL 창의 주소가 처음 요청했던 주소 그대로 있게 되는 것이다.


요청 객체를 재성성 하지 않으므로 Redirect보다 빠르다.



포워딩은 클라이언트와 통신없이 서버에서만 처리되기 때문에 리다이렉트보다 빠르다.






[출처] 오라클자바커뮤니티 - http://www.oraclejavanew.kr/bbs/board.php?bo_table=LecServletJSP&wr_id=253


Cannot load JDBC driver class 'oracle.jdbc.driver.OracleDriver'

위와 같은 에러를 내뱉는다.

이유는 오라클과 메이븐의 License 문제 때문에 메이븐의 중앙 저장소에서 받을 수 없어서 발생합니다.

해결방법은 pom.xml의 <repositories> 태그 안에 ojdbc와 관련된 repository를 직접 추가합니다.


<repositories>

...


<repository>

<id>mesir-repo</id>

<url>http://mesir.googlecode.com/svn/trunk/mavenrepo</url>

</repository>


...

</repositories>





<dependencies>

...


<dependency>

<groupId>com.oracle</groupId>

<artifactId>ojdbc14</artifactId>

<version>10.2.0.4.0</version>

</dependency>


...

</dependencies>



1. xml 을 이용한 등록 방법 - setter 이용


1) applicationContext.xml

<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
    <property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
 

<bean id="loginDAO" class="com.mungchung.sample.login.LoginDAOImpl">
    <property name="sqlMapClientTemplate" ref="sqlMapClientTemplate"/>
</bean>

 2) Bean

public class LoginDAOImpl implements LoginDAO {

    private SqlMapClientTemplate sqlMapClientTemplate;
 
    public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {

        this.sqlMapClientTemplate = sqlMapClientTemplate;

    }
}

 

 

2. xml 을 이용한 등록 방법 - 생성자 이용


1) applicationContext.xml

<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
    <property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
 

<bean id="loginDAO" class="com.mungchung.sample.login.LoginDAOImpl">
    <constructor-arg name="sqlMapClientTemplate" ref="sqlMapClientTemplate"/>
</bean>

2) Bean

public class LoginDAOImpl implements LoginDAO {

    private SqlMapClientTemplate sqlMapClientTemplate;
 
    public LoginDAOImpl(SqlMapClientTemplate sqlMapClientTemplate) {

        this.sqlMapClientTemplate = sqlMapClientTemplate;

    }
}

 

 

3. 어노테이션 이용 - 직접 Bean 등록


1) servlet-context.xml

<context:annotation-config/>
<bean id="loginDAO" class="com.mungchung.sample.login.LoginDAOImpl"/>


2) Bean

public class LoginDAOImpl implements LoginDAO {

    @Autowired
    private SqlMapClientTemplate sqlMapClientTemplate;

}


 

 

4. 어노테이션 이용 - Component-Scan 이용


1) servlet-context.xml

<context:component-scan base-package="com.mungchung.sample.login"/>


2) Bean

@Repository
public class LoginDAOImpl implements LoginDAO {

    @Autowired
    private SqlMapClientTemplate sqlMapClientTemplate;

}


출처 : http://www.mungchung.com/xe/spring/21198

servlet-context.xml


<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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">



<context:annotation-config /> // 애노테이션 방식 사용

<mvc:annotation-driven /> // MVC 애노테이션 방식 사용


// 기본 애노테이션들을 빈으로 등록해준다 src/leadweb/* 모든 하위 디렉토리

<context:component-scan base-package="leadweb.*" />


// 파일 형식의 업로드 기능을 사용하고자 할 때 등록하는 bean

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>


// 뷰 리졸버 - 컨트롤러와 jsp의 맵핑

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/WEB-INF/jsp/"/>

<property name="suffix" value=".jsp"/>

</bean>


<mvc:interceptors>

<mvc:interceptor>

   <mvc:mapping path="/admin/**" /> // uri 가 context root/admin/** 모든 URL이 들어왔을때

// 인터셉터 등록

<bean class="leadweb.admin.interceptor.LoginCheckInterceptor" />

</mvc:interceptor>

</mvc:interceptors>


Spring Context Root 변경

아주 간단한 방법으로는

webapps/neli 를 url 상으로 "/" context root로 보이고 싶다면


$ cd ../tomcat7/conf/

$ sudo vim server.xml


열어 보면 기본 Host 설정이 

<Host name="localhost" appBase="webapps" ... >

이렇게 잡혀 있을텐데 appBase 부분을


<Host name="localhost" appBase="webapps/neli" ...>

로 변경 해주면 된다

UserDaoTest.java (테스트용 클라이언트 Class)

package springbook.user;


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = "/applicationContext.xml")

public class UserDaoTest {


/*

* ApplicationContext 객체를 사용하여 getBean을 이용하여 UserDao에 DI를 주입 할수도 있지만

* Autowired 를 통하여 바로 UserDao에 DI를 주입하는 방법을 통해 

* ApplicationContext 객체를 사용하지 않는 방법을 택했다.

* @Autowired 

* private ApplicationContext context;

*/


@Autowired

private UserDao dao;


private User user1;

private User user2;

private User user3;


@Before

public void setUp() {


/*

* Configuration File인 daoFactory.class 에서 userDao 라는 빈을 가지고 오고 그

* userDao 라는 빈은 UserDao Object를 반환한다.

*/

// this.dao = context.getBean("userDao", UserDao.class);


user1 = new User("SexyGuy", "김성민", "springman1");

user2 = new User("delay", "류민기", "springman2");

user3 = new User("postpone", "송준화", "springman3");


}


public static void main(String[] args) {

JUnitCore.main("springbook.user.UserDaoTest");

}


@Test

public void addAndGet() throws ClassNotFoundException, SQLException {


dao.deleteAll();

assertThat(dao.getCount(), is(0));


dao.deleteAll();

assertThat(dao.getCount(), is(0));


dao.add(user1);

dao.add(user2);

dao.add(user3);

assertThat(dao.getCount(), is(3));


User userget1 = dao.get(user1.getId());

assertThat(userget1.getName(), is(user1.getName()));

assertThat(userget1.getPassword(), is(user1.getPassword()));


User userget2 = dao.get(user2.getId());

assertThat(userget2.getName(), is(user2.getName()));

assertThat(userget2.getPassword(), is(user2.getPassword()));


User userget3 = dao.get(user3.getId());

assertThat(userget3.getName(), is(user3.getName()));

assertThat(userget3.getPassword(), is(user3.getPassword()));

}


@Test(expected = EmptyResultDataAccessException.class)

public void getUserFaiure() throws SQLException, ClassNotFoundException {


dao.deleteAll();

assertThat(dao.getCount(), is(0));


dao.get("unknown_id");

}

}


applicationContext.xml (@Configuration과 @Bean 환경설정 xml)

<beans>

<bean id="userDao" class="springbook.user.dao.UserDao">

<property name="dataSource" ref="dataSource" />

</bean>


<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">

<property name="driverClass" value="oracle.jdbc.OracleDriver" />

<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />

<property name="username" value="scott" />

<property name="password" value="tiger" />

</bean>

</beans>


UserDao.java (의존성 주입을 당할 자바 빈 Class)
public class UserDao {
private DataSource dataSource;
private JdbcContext jdbcContext;
public void setDataSource(DataSource dataSource) {
this.jdbcContext = new JdbcContext();
this.jdbcContext.setDataSource(dataSource);
this.dataSource = dataSource;
}
public void deleteAll() throws SQLException  {
this.jdbcContext.executeSql("delete from users");
}

...

}


JdbcContext.java (템플릿과 콜백 패턴을 써서 만든 Class)

public class JdbcContext {

private DataSource dataSource;

public void setDataSource(DataSource dataSource) {

this.dataSource = dataSource;

}


public void workWithStatementStrategy (StatementStrategy stmt) throws SQLException {

Connection c = null;

PreparedStatement ps = null;


try {

c = dataSource.getConnection();


ps = stmt.makePreparedStatement(c);


ps.executeUpdate();

} catch (SQLException e) {

throw e;

} finally {

if (ps != null) { try { ps.close(); } catch (SQLException e) {} }

if (c != null) { try { c.close(); } catch (SQLException e) {} }

}

}

public void executeSql(final String query) throws SQLException {

workWithStatementStrategy( new StatementStrategy() {

@Override

public PreparedStatement makePreparedStatement(Connection c) throws SQLException {

return c.prepareStatement(query);

}

}); 

}

}


StatementStrategy.java (전략 패턴을 써야 함으로 인한 Interface)

public interface StatementStrategy {

PreparedStatement makePreparedStatement(Connection c) throws SQLException;

}

+ Recent posts