HTTP 프로토콜 구조


https, request, response, 주요 상태코드



1. 특징

  • 인터넷상에서 데이터를 주고받기 위한 서버/클라이언트 모델을 따르는 전송 프로토콜

  • 애플리케이션 레벨의 프로토콜로 TCP/IP 위에서 작동
  • 클라이언트에서 요청(request)을 보내면 서버는 요청을 처리해서 응답(response)
  • 80번  port이용


비상태연결 (Stateless, Connectless)


서버에 연결하고 요청해서 응답을 받으면 연결을 끊어버린다.


  • 장점 : 접속유지 최소화, 불특정 다수를 대상으로 하는 서비스에 유리
  • 단점 : 연결을 끊어버리기 때문에 클라이언트의 이전 상태를 알 수 없음, 따라서 로그인을 해도 정보유지 불가. 이를 해결하기 위해 쿠키등을 이용


Keep Alive


HTTP 1.1부터는 keep-alive 기능을 지원

HTTP는 하나의 연결에 하나의 요청을 하는 것을 기준으로 설계가 되어, 문서에 20여개의 파일이 있다면 계속 연결하고 다운하고 연결을 끊어야 한다.

TCP통신 과정에서 비용이 많이 소모함. 따라서 Keep Alive 기능 등장.

지정된 시간동안 연결을 끊지 않고 요청을 계속해서 보낼 수 있다.



HTTPS


SSL은 전자상거래에서의 데이터 보안을 위해서 개발한 통신 레이더다.

SSL은 표현계층의 프로토콜로 응용 계층 아래에 있기 때문에 어떤 응용계층의 데이터라도 암호화해서 보낼 수 있다.




  • HTTPS의 기분 포트번호는 443

  • HTTP에 비해 많이 느림



2. Request


메세지 구조


요청라인 : GET / HTTP / 1.1

  • 요청 메소트 : GET, POST, PUT, DELETE
  • 요청 URL
  • HTTP 버전

요청헤더 : 키 - 값 방식으로 들어감

  • Accept : 클라이언트가 받을 수 있는 컨텐츠
  • Cookie : 쿠키
  • Content-Type : 메세지 바디 종류
  • Content-Length : 메세지 바디 길이
  • if-Modified-Since : 특정 날짜 이후에 변경됐을때만

요청 바디 (엔티티)



Content-Type과 Body


참조문서 : https://www.w3.org/Protocols/rfc1341/4_Content-Type.html


1. form 형태 : URLEncoded 방식

  • application / x-www-form-urlencoded
  • 메세지 바디 : 쿼리 문자열

2. json 형태

  • application / json

3. 멀티파트 형태 : 이진파일 넘길 때 사용, 하나의 메세지 바디에 파트를 나눠서 작성

  • boundary는 파트 구분자
  • multipart / form-data : boundary = frontier



3. Response


메세지 구조


응답 라인

  • 버전
  • 상태코드
  • 상태 메세지 : HTTP/1.1 200 OK

응답 헤더

  • Content-Type : 바디 데이터의 타입
  • Content-Length : 바디 데이터 크기
  • Set-Cookie : 쿠키 설정
  • ETag : 엔티티 태그

응답 바디 : HTML, JSON, Octet Stream 등이 있다.



상태 코드


1xx : 정보


2xx : 성공

  • 200 : OK. 요청 성공
  • 201 : Created. 생성 요청 성공
  • 202 : Accepted. 요청 수락 (처리 보장 X)
  • 204 : 성공했으나 돌려줄게 없음

3xx : 리다이렉션

  • 300 : Multiple choices. 여러 리소스에 대한 요청 결과 목록
  • 301, 302, 303 : Redirect. 리소스 위치가 변경된 상태
  • 304 : Not Modified. 리소스가 수정되지 않았음.

4xx : 클라이언트 오류

  • 400 : Bad Request. 요청 오류
  • 401 : Unauthorized. 권한 없음
  • 403 : Forbidden. 요청 거부
  • 404 : Not Found. 리소스가 없는 상태

5xx : 서버 오류

  • 500 : Internal Server Error. 서버가 요청을 처리 못함
  • 501 : Not Implemented. 서버가 지원하지 않는 요청
  • 503 : Service Unavailable. 과부화 등으로 당장 서비스가 불가능한 상태


Content-Type과 Body


주요 컨텐츠 타입은 아래와 같다.

  • text / plain, text / html
  • application / xml, application / json
  • image / png, image / jpg
  • audio / mp3, video / mp4



'Coding' 카테고리의 다른 글

rpc  (0) 2018.04.26
ODOO 11 ::: ORM API - 레코드세트  (0) 2018.04.26
Odoo 11 ::: Snippets Pagination  (0) 2018.04.17
Odoo 11 ::: Fields Type에 대해 알아보자 (3)  (0) 2018.04.10
Odoo 11 ::: Fields Type에 대해 알아보자 (2)  (1) 2018.04.09

Odoo 11 Snippets Pagination



templates.xml


<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="assets_frontend" inherit_id="website.assets_frontend">
<xpath expr="." position="inside">
<link rel="stylesheet" href="/linkup_theme/static/src/less/board.less" />

<script src="/linkup_theme/static/src/js/r3_snippets.js" type="text/javascript"/>
<script src="/linkup_theme/static/src/js/jquery.twbsPagination.js" type="text/javascript"></script>
</xpath>
</template>
</odoo>



snippets.xml


<!--게시판 -->
<template id="r3_2" name="board table">
<section class="section-md oe_snippet_body board_snippet">
<section class="container">
<h2>Board</h2>
<table class="table" id="page-content">
<tr>
<th>Name</th>
<th>Release date</th>
</tr>
</table>
<nav aria-label="Page navigation example" style="text-align: center;">
<ul class="pagination-sm" id="pagination"></ul>
</nav>
</section>

</section>
</template>



r3_snippets.js



odoo.define('r3_snippets', function(require)
{
"use strict";
var rpc = require('web.rpc'), //< 함수를가져옴
Animation = require('website.content.snippets.animation');


Animation.registry.board_snippet = Animation.Class.extend({
selector: '.board_snippet',
start: function()
{
var self = this;
_.each(this.$el.attr('class').split(/\s+/), function(cls)
{
if(cls.indexOf('board_snippet-show') == 0)
{
var number = parseInt(cls.substring('board_snippet-show'.length));
}
});
this.$el.find('td').parents('tr').remove();
rpc.query({
model: 'website.board',
method: 'search_read',
domain: [],
fields: ['name', 'date_release'],
sortBy: ['date_release desc'],
})
.then(function(data)
{
var totalCount = data.length; //db에 데이터 수
var countList = 9; // 한 페이지에 출력될 게시물 수
var totalPage = Math.floor(totalCount/countList); //전체 페이지 번호수
var page = 1; //현재 페이지 번호
var countPage = 5; //한 화면에 출력될 페이지 수
var startPage = Math.floor((page - 1) / 10) * 10 + 1; //시작 페이지
var endPage = startPage + countPage - 1; //마지막 페이지

if (endPage > totalPage) { // 마지막페이지가 전체페이지보다 크면
endPage = totalPage; // 마지막페이지를 전체페이지로 바꾼다.
}

if (totalCount > countList * totalPage){ // db에 데이터수가 1페이지 게시물수 * 전체 페이지 수 보다 많으면
totalPage+=1; // 전체 페이지에 1을 더한다.
}

if (totalPage < page){ // 현재 페이지가 전체 페이지수보다 크면
page = totalPage; // 현재 페이지를 전체 페이지로 바꾼다.
}

var paging = function(page) { //paging 함수를 정의한다.
$("table").empty(); // table태그 안에 내용을 비운다.
var $table = self.$el.find('table'); // $table변수에 table태그를 담는다.
var startRow = (page - 1) * countList; // 시작줄
var endRow = page * countList; // 마지막줄
if (endRow >= totalCount) // 마지막줄이 db 데이터 수 보다 많거나 같으면
{
endRow = totalCount; // 마지막줄을 db데이터수로 바꾼다.
}

for (var i = startRow; i < endRow; i++){ // 시작줄부터 마지막줄의 크기만큼 아래내용을 반복한다.
$table.append( // $table변수 뒤에 아래 태그를 추가한다.
jQuery('<tr />') // tr태그를 추가한다.
.append(
jQuery('<td />').text(data[i].name), // website.board[i].name을 추가한다.
jQuery('<td />').text(data[i].date_release) // website.board[i].date_release를 추가한다.
)
);
}
}


$('#pagination').twbsPagination({
startPage: startPage, //시작 페이지
totalPages: totalPage, //총 페이지 갯수
visiblePages: countPage, //보여줄 페이지
onPageClick: function (event, page) { // 클릭하면
$('#page-content').text('Page ' + page);
paging(page); // paging 함수가 실행된다.
}
});
});

},
});
});



Odoo 11 필드 타입 3


속성 필드


속성 선언하기


속성은 특별한 필드입니다 : fields.property.


class res_partner(osv.osv):
    _name = "res.partner"
    _inherit = "res.partner"
    _columns = {
                'property_product_pricelist':
                                            fields.property(
                                'product.pricelist',
                        type='many2one',
                        relation='product.pricelist',
                        string="Sale Pricelist",
                                method=True,
                                view_load=True,
                                group_name="Pricelists Properties"),
    }


다음은 이 속성에 대한 .XML 파일에 기본값을 만들어야합니다.


<record model="ir.property" id="property_product_pricelist">
    <field name="name">property_product_pricelist</field>
    <field name="fields_id" search="[('model','=','res.partner'),
      ('name','=','property_product_pricelist')]"/>
    <field name="value" eval="'product.pricelist,'+str(list0)"/>
</record>


TIP


기본값이 다른 모듈의 자원을 가리키면 다음과 같이 ref 함수를 사용할 수 있습니다 : <field name="value" eval="'product.pricelist,'+str(ref('module.data_id'))"/>


form에 속성 배치하기


폼에 속성을 추가하려면 폼에 <properties /> 태그를 넣으면됩니다. 그러면이 개체와 관련된 모든 속성 필드가 자동으로 추가됩니다. 

사용자 시스템의 권한에 따라 시스템이 추가됩니다. (일부 사용자는 특정 속성을 변경할 수 있고 다른 사용자는 그렇지 않을 수 있습니다).


특성은 group_name 속성에 따라 섹션별로 표시됩니다. (이것은 분리 자 태그처럼 클라이언트에서 렌더링됩니다).



이게 어떻게 작동합니까?


fields.property 클래스는 fields.function을 상속하며 읽기 및 쓰기 메서드를 재정의합니다. 

이 필드의 유형은 many2one이므로 양식에서 many2one 함수와 같은 속성이 표시됩니다.


그러나 속성의 값은 ir.property 클래스 / 테이블에 완전한 레코드로 저장됩니다. 

저장된 값은 각 속성이 다른 객체를 가리킬 수 있기 때문에 many2one이 아닌 형식 참조 필드입니다. 

관리 메뉴에서 등록 정보 값을 편집하는 경우 이는 유형 참조 필드로 표시됩니다.


속성을 읽을 때이 프로그램은 읽고있는 객체의 인스턴스에 연결된 속성을 제공합니다. 

이 객체에 값이 없으면 시스템에서 기본 속성을 제공합니다.


프로퍼티의 정의는 다른 필드와 마찬가지로 ir.model.fields 클래스에 저장됩니다. 

속성의 정의에서 속성으로 변경할 수있는 그룹을 추가 할 수 있습니다.



속성 또는 일반 필드 사용


새 기능을 추가하려면 속성을 일반 필드로 구현하도록 선택해야합니다. 개체를 상속하고이 개체를 확장하려면 일반 필드를 사용하십시오. 

새 속성이 객체와 관련이 없지만 외부 개념에 관련된 경우 속성을 사용합니다.


다음은 일반 필드 또는 속성 중에서 선택할 때 도움이되는 몇 가지 팁입니다.


일반 필드는 객체를 확장하여 더 많은 피쳐 또는 데이터를 추가합니다.


속성은 객체에 첨부되고 특별한 기능을 가진 개념입니다.


예 )

- 회사에 따라 동일한 부동산에 대한 다른 가치 - 필드 당 권한 관리 - 그것은 자원들 간의 연결고리입니다 (many2one)


예제1: Account Receivable


특정 파트너에 대한 기본 "Account Receivable"은 다음과 같은 이유로 인해 이 속성으로 구현됩니다.


- 이 개념은 파트너가 아닌 계정 차트와 관련된 개념이므로 파트너 폼에 표시되는 계정 속성입니다. 회계사의 경우이 필드에서 권한을 관리해야하며 파트너 객체에 적용되는 것과 동일한 권한이 아닙니다. 따라서 파트너 양식의 이 필드에만 특정 권한이 있습니다. 회계사만 파트너의 채권을 변경할 수 있습니다. - 이것은 여러 회사 필드입니다. 동일한 파트너는 사용자가 속한 회사에 따라 다른 채권값을 가질 수 있습니다. 다중 회사 시스템에는 회사 당 하나의 계정 차트가 있습니다. 파트너의 계정 채권은 판매 주문을 한 회사에 따라 다릅니다. - 기본 계정 채권은 모든 파트너에 대해 동일하며 일반 속성 메뉴 (관리)에서 구성됩니다.


TIP


한 가지 재미있는 점은 속성이 "스파게티"코드를 피하는 것입니다. 

계정 모듈은 파트너 (base) 모듈에 따라 다릅니다. 하지만 회계 모듈없이 파트너 (base) 모듈을 설치할 수 있습니다. 

파트너 개체의 계정을 가리키는 필드를 추가하면 두 개체가 서로 종속됩니다. 

유지 보수 및 코드 작성이 훨씬 어렵습니다 (예 : 두 테이블이 서로 가리키는 경우 테이블 제거를 시도).



- 예제 2: Product Times



제품 만료 모듈은 제품과 관련된 모든 지연을 제거 날짜, 제품 시간등등을 구현합니다.이 모듈은 식품 산업에 매우 유용합니다.


이 모듈은 product.product 객체를 상속 받아 새 필드를 추가합니다.


class product_product(osv.osv):

    _inherit = 'product.product'
    _name = 'product.product'
    _columns = {

        'life_time': fields.integer('Product lifetime'),
        'use_time': fields.integer('Product usetime'),
        'removal_time': fields.integer('Product removal time'),
        'alert_time': fields.integer('Product alert time'),
        }

product_product()


이 모듈은 product.product 객체에 간단한 필드를 추가합니다. 속성을 사용하지 않았습니다. 

이유는 다음과 같습니다.


우리는 제품을 확장하고 life_time 필드는 제품과 관련된 개념이며 다른 객체에는 관련되지 않습니다. 우리는 필드 당 올바른 관리가 필요하지 않으며, 다른 지연은 모든 제품을 관리하는 동일한 사람들이 관리합니다.




+ Recent posts