728x90
반응형
PHP file_get_contents()
  • 전체파일을 문자열로 읽어들이는 PHP 함수
  • 로컬파일, 원격파일 모두 가능
$str = file_get_contents('test.txt');
echo $str;
# John Smith
$str = file_get_contents('http://zetawiki.com/ex/txt/utf8hello.txt');
echo $str;
# Hi.
# 안녕.
# おはよう。


728x90
반응형

'Web Programming > php' 카테고리의 다른 글

php $_GET $_POST  (0) 2018.09.05
php new line to br nl2br()  (0) 2018.09.05
PHP 문자열 길이 (strlen, mb_strlen 함수)  (0) 2018.09.04
php data types  (0) 2018.09.04
php include, require  (0) 2018.09.03
728x90
반응형
http://www.example.com/index.html?name=john&email=john@gmail.com&contact=9877989898

Client Side: Below code is an HTML form with method=”get” for user to fill information.


<form action="#" method="get">
<input type="text" name="name" placeholder="Your Name"></input><br/>
<input type="text" name="email" placeholder="Your Email"></input><br/>
<input type="text" name="contact" placeholder="Your Mobile"></input><br/>
<input type="submit" name="submit" value="Submit"></input>
</form>

Server Side: Below code has PHP script where, $_GET associative array is used to receive sent information at server end.


<?php
if( $_GET["name"] || $_GET["email"] || $_GET["contact"])
{
echo "Welcome: ". $_GET['name']. "<br />";
echo "Your Email is: ". $_GET["email"]. "<br />";
echo "Your Mobile No. is: ". $_GET["contact"];
}
?>


Client Side: Below code is an  HTML form with method=”post” for user to fill information.


<form action="#" method="post">
....
</form>

Server Side: Below code has PHP script where, $_POST associative array  is used to receive sent information at server end.


<?php
if( $_POST["name"] || $_POST["email"] || $_POST["contact"])
{
echo "Welcome: ". $_POST['name']. "<br />";
echo "Your Email is: ". $_POST["email"]. "<br />";
echo "Your Mobile No. is: ". $_POST["contact"];
}
?>

Query string , generated by Post  method never appears in address bar i.e. it is hidden for the user therefore, we can use this method for sending sensitive information to server. Moreover, we can make use of this method to send binary data to the server without any restrictions to data size.

 

In our example, we allow user to choose a method via radio button and this value is assigned to form’s method attribute.


$("input[type=radio]").change(function(){
var method = $(this).val();
$("#form").attr("method", method);   // Assigns Method Type From Radio Button
});


728x90
반응형

'Web Programming > php' 카테고리의 다른 글

php file_get_contents()  (0) 2018.09.05
php new line to br nl2br()  (0) 2018.09.05
PHP 문자열 길이 (strlen, mb_strlen 함수)  (0) 2018.09.04
php data types  (0) 2018.09.04
php include, require  (0) 2018.09.03
728x90
반응형

Example

Insert line breaks where newlines (\n) occur in the string:

<?php
echo nl2br("One line.\nAnother line.");
?>

The browser output of the code above will be:

One line.
Another line.

The HTML output of the code above will be (View Source):

One line.<br />
Another line.


728x90
반응형

'Web Programming > php' 카테고리의 다른 글

php file_get_contents()  (0) 2018.09.05
php $_GET $_POST  (0) 2018.09.05
PHP 문자열 길이 (strlen, mb_strlen 함수)  (0) 2018.09.04
php data types  (0) 2018.09.04
php include, require  (0) 2018.09.03
728x90
반응형

Tomcat 서버 하나에 여러개의 war 파일을 배포하여 사용하며 각 application 별로 Spring의 DBCP 를 이용하여 Connection Pooling 을 한다.

 문제점 

  - db 접속 정보(id/pw) 를 한곳에서 관리할 수 없다.

  - db 접속 정보가 변경되면 각 war 별로 참조하는 파일의 내용을 변경해 줘야 한다. ( ex 암호화 되어 있는 properties 파일 )

  - 개별 connection pooling 의 경우 실수가 발생할 가능성이 높으며 불필요한 서버 리소스가 낭비 된다.


[방안]

  - WAS 에서 제공하는 connection pooling 을 사용 한다.

  - 각 war 에서는 JNDI 로 Lookup 하여 연결 한다.

  - 주의사항 : 접속 하는 데이터베이스는 하나가 된다.

         ex) aaa.war 에서는 test 라는 데이터베이스안에 있는 테이블만 사용

             bbb.war 에서는 real 이라는 데이터베이스 안에 있는 테이블만 사용

             위와 같은 경우 query 에 반드시 aaa.tableName 으로 처리 해줘야 한다.

             이전 처럼 개별로 connection 을 관리할 경우에는 connection 자체를 aaa 또는 bbb 로 하기 때문에 table name 만 써도

             문제되지 않았지만 이부분은 수정이 되어야 한다.


[처리 방법 정리]

1. Tomcat 설정

   server.xml 의 GlobalNameingResource 에 JNDI 내용 추가

 <GlobalNamingResources>

    <Resource name="jdbc/testJNDI"

          factory="com.yhkim.global.datasource.CustomDataSource"

          auth="Container"

          type="javax.sql.DataSource"

          maxActive="100"

          maxIdle="30"

          maxWait="10000"

          username=""

          password=""

          driverClassName="com.mysql.jdbc.Driver"

          url="jdbc:mysql://127.0.0.1:3306/databaseName?zeroDateTimeBehavior=convertToNull"/>

  </GlobalNamingResources>

  노란색 부분을 눈여겨 보자.

  일반적인 JNDI 이용 시 factory 부분은 org.apache.tomcat.jdbc.pool.DataSourceFactory 를 사용한다.

  하지만 그럴 경우 username 과 password 부분을 암호화 해서 사용할 수 없다. 

  따라서 custom factory class 를 작성하여 username 와 password 를 복호화 할 수 있도로 한다.


2. CustomDataSource class 작성

   apache 의 common-dbcp 를 이용하였다. 

   아래 java project 에서 build-path 에 common-dbcp-x.x.jar 파일을 포함하고 

   아래 project 를 globalds.jar (이름은 마음데로) 파일로 export 하여 Tomcat/lib 에 포함시킨다. 

   ../conf/dbinfo.properties 는 즉 설치되는 Tomcat/conf/ 경로가 된다. 

   Tomcat/conf/에 dbinfo.properties 를 만들고 아래 내용을 넣는다. (테스트를 위해 암호화가 아닌 base64 encoding 을 해도 무관)

   username=암호화된아이디

   password=암호화된비밀번호

 public class CustomDataSource extends BasicDataSourceFactory {

public Object getObjectInstance(Object obj, Name name, Context nameCtx, 

                                          @SuppressWarnings("rawtypes") Hashtable environment) throws Exception

{

if(obj instanceof Reference)

{

setUsername((Reference)obj);

setPassword((Reference)obj);

}

return super.getObjectInstance(obj, name, nameCtx, environment);

}


private void setUsername(Reference ref)

throws Exception

{

findDecryptAndReplace("username", ref);

}


private void setPassword(Reference ref)

throws Exception

{

findDecryptAndReplace("password", ref);

}


private void findDecryptAndReplace(String refType, Reference ref)

throws Exception

{

int idx = find(refType, ref);

String decrypted = decrypt(refType);

replace(idx, refType, decrypted, ref);

}


private void replace(int idx, String refType, String newValue, Reference ref)

throws Exception

{

ref.remove(idx);

ref.add(idx, new StringRefAddr(refType, newValue));

}


private String decrypt(String key)throws Exception

{

return getDecViaSeed(getProperty(key));

}


private int find(String addrType, Reference ref)

{

try{

@SuppressWarnings("rawtypes")

Enumeration enu = ref.getAll();

for(int i = 0; enu.hasMoreElements(); i++)

{

RefAddr addr = (RefAddr)enu.nextElement();

if(addr.getType().compareTo(addrType) == 0)

return i;

}

}catch(Exception e){

e.printStackTrace();

}

return 0;

}

public String getDecViaSeed(String str) {

String strDecrypt = "";

try

{

// strDecrypt = 복호화 처리

                   // 실제 테스트를 위해서는 간단히 BASE64 정도로 테스트 해봐도 된다.

}

catch (UnsupportedEncodingException e) 

{

e.printStackTrace();

catch (Exception e) 

{

e.printStackTrace();

}

return strDecrypt;

}

public String getProperty(String key) {

String rtnStr = "";

try {

Properties prop = new Properties();

prop.load(new FileInputStream("../conf/dbinfo.properties"));

rtnStr = prop.getProperty(key);

} catch ( IOException ioe ) {

ioe.printStackTrace();

return null;

} catch ( Exception e ) {

e.printStackTrace();

}

return rtnStr;

}

}

 


3. Tomcat lib 에 필요한 jar 파일 추가

  2번에서 생성한 globalds.jar 과 

  commons-dbcp.jar

  commons-collections.jar

  commons-pool.jar 

  파일을 Tomcat/lib 경로에 포함한다.


4. Application 에서 JNDI 이용하기

web application은 Spring + MyBatis 로 구성되어 있으며 

jdbc 설정.xml 에 아래와 같이 datasource 및 transaction 부분을 설정 한다. (transaction 처리는 상황에 따라 다르게 처리 가능)

bold 처리된 부분만 보면 된다. jndiName 은 tomcat 의 server.xml 에 있는 이름과 동일 해야 한다.

      <beans:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

  <beans:property name="jndiName" value="jdbc/testNDI"/>

  <beans:property name="resourceRef" value="true"/>

  </beans:bean>

<beans:bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" lazy-init="true">

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

<beans:property name="configLocation" value="classpath:mybatis/mybatis-configuration.xml" />

<beans:property name="mapperLocations" value="classpath:mybatis/query.xml" />

<beans:property name="transactionFactory">

<beans:bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />

</beans:property>

</beans:bean>

<beans:bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">

<beans:constructor-arg ref="sqlSessionFactory" />

</beans:bean>

 

<beans:bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

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

</beans:bean>

<beans:bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">

<beans:property name="transactionManager" ref="transactionManager" />

</beans:bean>


5. Application 의 context.xml 설정

META-INF 폴더 밑에 context.xml 파일이 없다면 생성하고 있다면 아래 내용을 추가 한다.

 <?xml version="1.0" encoding="UTF-8"?>

<Context path="/applicationName">

    <WatchedResource>WEB-INF/web.xml</WatchedResource>

<ResourceLink global="jdbc/testJNDI" name="jdbc/testJNDI" type="javax.sql.DataSource"/>

</Context>



728x90
반응형

'Web Programming > server' 카테고리의 다른 글

톰캣 404  (0) 2018.09.04
A child container failed during start  (0) 2018.09.04
728x90
반응형

TDD(Test-driven Development) 테스트 주도 개발방법론

각종 Community에서 개발 프로세스가 TDD가 언급이 되었고 예전에 소프트웨어 개발 프로세스 중에 배웠던 TDD에 대해 깊이 있게 몰랐기 때문에 명확하게 정의를 하고 앞으로 개발 방법을 TDD로 바꾸려고 노력하기 위해 Posting을 해보려고 한다.

1. TDD(Test-driven Development)이란?

  • 일반적인 개발 프로세스

    • 일반적으로 개발 절차는 먼저 어떻게 개발할지 디자인하고 디자인을 바탕으로 실제 코드를 작성하고 최종적으로 테스트를 작동시켜보면서 해보는 과정이었다.

No Image

  • TDD(Test-driven Development)

    • 정확한 프로그래밍 목적을 디자인 단계에서 반드시 미리 정의해야만 하고 또 무엇을 미리 정의해야한다.
    • RED : 실패하는 테스트를 만들기.
    • GREEN : 테스트에 통과할 만한 작은 코드를 작성하기.
    • REFACTOR : 반복되는 코드, 긴 메소드, 큰 클래스, 긴 매개변수 목록 등등 코드를 좀 더 효율적으로 바꾸기.

No Image

  • 개발하는 과정에서 Test Script를 작성하고 코드를 Refactoring 했다는 점이 중요하다.

2. TDD 따라하기 (JUnit)

목표 : Movie라는 클래스에 등급을 부여하고 Averaging Rate구하기

1) JUnit이란?

2) pom.xml JUnit & hamcrest 추가 코드

<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.2</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.hamcrest</groupId>
			<artifactId>hamcrest-all</artifactId>
			<version>1.1</version>
			<scope>test</scope>
		</dependency>
</dependencies>

3) JUnit 실행

package movie;

import org.junit.Test;

/**
 * Created by NESOY on 2017-01-31.
 */
public class MovieTest {
    @Test
    public void foo(){

    }
}

Test 결과화면

No Image

4) Failing Test 코드 작성

/**
 * Created by NESOY on 2017-01-31.
 */
public class MovieTest {
    @Test
    public void canCreateMovie(){
        Movie movie = new Movie();
    }
}

5) Test를 통과하기 위한 소량의 코드 추가

package movie;

/**
 * Created by NESOY on 2017-01-31.
 */
public class Movie {
}

Test 결과화면

No Image

6) Averaging Rating Test Case만들기 - 가장 초기 모델이므로 Rate점수가 없다. -> 0점.

package movie;

import org.junit.Test;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

/**
 * Created by NESOY on 2017-01-31.
 */
public class MovieTest {
    @Test
    public void canCreateMovie(){
        Movie movie = new Movie();
        assertThat(movie.averageRationg(),is(0));
    }
}

7) Test를 통과하기 위한 소량의 코드 추가

package movie;

/**
 * Created by NESOY on 2017-01-31.
 */
public class Movie {
    public Integer averageRationg() {
        return 0;
    }
}

Test 결과화면

No Image

8) Refactoring하기 - Method 이름 바꾸기

package movie;

import org.junit.Test;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

/**
 * Created by NESOY on 2017-01-31.
 */
public class MovieTest {
    @Test
    public void should_return_0_when_just_created(){
        Movie movie = new Movie();
        assertThat(movie.averageRationg(),is(0));
    }
}

9) Averaging Rating Test Case만들기 -> 1을 주었을때 Average Rate가 1이 나와야한다.

package movie;

import org.junit.Test;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

/**
 * Created by NESOY on 2017-01-31.
 */
public class MovieTest {
    @Test
    public void should_return_0_when_just_created(){
        Movie movie = new Movie();
        assertThat(movie.averageRationg(),is(0));
    }

    @Test
    public void should_return_1_when_was_rated(){
        Movie movie = new Movie();
        movie.rate(1);
        assertThat(movie.averageRationg(),is(1));
    }
}

10) Compile 통과하기 위한 소량의 코드 추가

package movie;

/**
 * Created by NESOY on 2017-01-31.
 */
public class Movie {
    public Integer averageRationg() {
        return 0;
    }

    public void rate(int rate) {

    }
}

Test 결과화면

No Image

averageRationg Return 값이 어떠한 상황에서도 0이다. 고쳐서 Test를 통과시키자.

package movie;

/**
 * Created by NESOY on 2017-01-31.
 */
public class Movie {
    private int sumOfRate = 0;
    private int countOfRate = 0;

    public Integer averageRationg() {
        return sumOfRate/ countOfRate;
    }

    public void rate(int rate) {
        this.sumOfRate += rate;
        this.countOfRate++;
    }
}

Test 결과화면

No Image

countOfRate가 0일 경우에 0으로 나누었을 경우 Exception 발생 -> 0일때 예외처리

package movie;

/**
 * Created by NESOY on 2017-01-31.
 */
public class Movie {
    private int sumOfRate = 0;
    private int countOfRate = 0;

    public Integer averageRationg() {
        return countOfRate == 0 ? 0 : sumOfRate/ countOfRate;
    }

    public void rate(int rate) {
        this.sumOfRate += rate;
        this.countOfRate++;
    }
}

Test 결과화면

No Image

11) Refactoring - TestCase의 중복되는 부분 제거하기

package movie;

import org.junit.Test;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

/**
 * Created by NESOY on 2017-01-31.
 */
public class MovieTest {
    @Test
    public void should_return_0_when_just_created(){
        Movie movie = new Movie(); // 중복
        assertThat(movie.averageRationg(),is(0));
    }

    @Test
    public void should_return_1_when_was_rated(){
        Movie movie = new Movie(); // 중복
        movie.rate(1);
        assertThat(movie.averageRationg(),is(1));
    }
}

Tips : Intellj Refactor - Field - Setup Method 자동으로 해준다.

No Image

package movie;

import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

/**
 * Created by NESOY on 2017-01-31.
 */
public class MovieTest {

    private Movie movie;

    @Before
    public void setUp() throws Exception {
        movie = new Movie();
    }

    @Test
    public void should_return_0_when_just_created(){
        Movie movie = this.movie; // 불필요하므로 제거한다.
        assertThat(movie.averageRationg(),is(0));
    }

    @Test
    public void should_return_1_when_was_rated(){
        Movie movie = this.movie; // 불필요하므로 제거한다.
        movie.rate(1);
        assertThat(movie.averageRationg(),is(1));
    }
}

12) Averaging Rating Test Case만들기 -> 3,5을 주었을때 Average Rate가 4이 나와야한다.

@Test
   public void should_return_4_when_3_and_5_were_rated(){
       movie.rate(3);
       movie.rate(5);
       assertThat(movie.averageRationg(),is(4));
   }

Test 결과화면

No Image

728x90
반응형

'Web Programming > java-jsp' 카테고리의 다른 글

람다 아키텍처  (0) 2018.09.05
java Generic  (0) 2018.09.05
클래스 정보 가져오기 - 리플렉션  (0) 2018.09.04
JSTL에서 LIST Size  (0) 2018.09.04
For input string: ""  (0) 2018.09.04

+ Recent posts