jsp中Tag的使用(自定义标签)

原创 2012年07月12日 17:49:53

 Tag文件可以实现代码的复用,这些代码可能是许多JSP页面都需要的。为了能让一个Web应用中的JSP页面使用某一个Tag文件,必须把这个Tag文件存放到Tomcat服务器指定的目录中,也就是说,如果某个Web服务目录下的JSP页面准备调用一个Tag文件,那么我们必须在该Web服务目录下,建立如下的目录结构:

            Web服务器\WEB-INF\tags

比如:

           Ch3\WEB-INF\tags

       其中的WEB-INF和tags部是固定的子目录名称,而tags下的子目录名称可由用户给定。 

3.3 Tag标记与Tag文件的使用

1.Tag标记

    某个Web服务目录下的Tag文件只能由该Web服务目录(包括该Web服务目录的子目录)中的JSP页面调用,JSP页面必须通过Tag标记来调用一个Tag文件。当我们编写了一个Tag文件并保存到特定目录中后,也就自定义了一个标记,该标记的格式为:

            <Tag  文件名字 />

  

           <Tag  文件名字>

                 标记体

              </Tag  文件名字>

    也就是说,一个Tag文件对应一个标记,习惯上称为Tag标记。同一个目录中的若干个Tag文件对应的各个Tag标记组成一个标记库,习惯上称为自定义标记库。

2.Tag标记的使用      

一个JSP页面通过使用Tag标记来调用一个Tag文件。Web服务目录下的一个JSP页面必须首先使用<taglib>指令标记引入该Web服务目录下的标记库,只有这样,JSP页面才可以使用Tag标记调用相应的Tag文件。<taglib>指令的格式如下:

    <@taglibtagdir="自定义标记库的位置"prefix="前缀"> 

      一个JSP页面可以使用几个<taglib>指令标记引入若干个标记库,例如:

 <%@ taglibtagdir="/WEB-INF/tags"prefix="beijing"%>

<%@ taglibtagdir="/WEB-INF/tags/tagsTwo""prefix="dalian"%> 

       引入标记库后,JSP页面就可以使用带前缀的Tag标记调用相应的Tag文件,其中的前缀由<taglib>指令中的prefix属性指定。例如:

         <beijing:OddSum/>

         <dalian:EvenSum/>

        注意:通过前缀可以有效地区分不同标记库中具有相同名字的标记文件。

3.Tag标记的标记体

    

          JSP页面使用Tag标记动态执行一个Tag文件。我们已经知道,一个Tag文件会对应一个自定义标记,该标记的格式为:

    <Tag 文件名字/>

    <Tag 文件名字>

            标记体

    </Tag 文件名字>

        默认情况下,JSP可以使用没有标记体的Tag标记,也可以使用带有标记体的Tag标记调用一个Tag文件。那么,Tag标记的标记体起着怎样的作用呢?

        JSP页面调用一个Tag文件时可能希望动态地向该Tag文件传递信息,那么就可以使用带有标记体的Tag标记来执行一个Tag文件,Tag标记中的“标记体’’就会传递给相应的Tag文件,Tag文件通过使用:

    <jsp:doBody />

标记处理JSP页面传递过来的“标记体”。

3.4 Tag文件中的常用指令

         JSP文件类似,Tag文件中也有一些常用指令,这些指令将影响Tag文件的行为。

        Tag文件中经常使用的指令有:

               tagtaglibincludeattributevariable。 

1.tag指令

       Tag文件中的tag指令类似于JSP文件中的page指令。Tag文件通过使用tag指令可以指定某些属性的值,以便从总体上影响Tag文件的处理和表示。tag指令的语法如下:

 <%@ tag 属性1="属性值"属性2="属性值属性n="属性值" %>

        在一个Tag文件中可以使用多个tag指令,因此我们经常使用多个tag指令为属性指定需要的值:

        <%@ tag 属性1="属性值" %>

        <%@ tag 属性2="属性值" %>

                ……

        <%@ tag 属性n="属性值" %>

     tag指令可以操作的属性有:body-contentlanguageimportpageEncoding。 

(1) body-content属性

   一个Tag文件会对应一个Tag标记,其格式为:

     <Tag 文件名字/>

  

      <Tag 文件名字>

          标记体

       </Tag 文件名字>

  JSP文件通过使用Tag标记调用相应的Tag文件,那么JSP文件到底应该使用Tag标记的哪种格式来调用Tag文件呢?

       答案是:一个Tag文件通过tag指令指定body-content属性的值可以决定Tag标记的使用格式。也就是说,body-content属性的值可以确定JSP页面使用Tag标记时是否可以有标记体,如果允许有标记体,则该属性会给出标记体内容的类型。

      body content属性值有: emptytagdependentscriptless,默认值是scriptless

       如果body-content属性的值是empty,那么JSP页面必须使用没有标记体的Tag标记:

           <Tag文件名字/>

     来调用相应的Tag文件。

        如果body content属性的值是tagdependentscriptless,那么JSP页面可以使用无标记体或有标记体的Tag标记:

          <Tag  文件名字>

              标记体

        </Tag    文件名字>

来调用相应的Tag文件。 

         如果属性值是scriptless,那么标记体中不能有Java程序片;如果属性值是tagdependent,那么Tag文件将标记体的内容按纯文本处理。

       Tag标记中的标记体由相应的Tag文件负责处理,因此,当JSP页面使用有标记体的Tag标记调用一个Tag文件时,可以通过标记体向该Tag文件动态地传递文本数据或必要的JSP指令。

        Tag文件通过使用标记:

           <jsp:doBody/>

(2)language属性

       language属性的值指定Tag文件使用的脚本语言,目前只能取值Java,其默认值就是Java,因此在编写Tag文件时,没有必要使用tag指令指定language属性的值。

(3)import属性

       import属性的作用是为Tag文件引入Java核心包中的类,这样就可以在Tag文件的程序片部分、变量及方法声明部分、表达式部分使用Java核心包中的类。import属性可以取多个值,import属性已经有如下值:“java.1ang.*”javax.servlet.*”javax.servletjsp.javax.servlet.http.*”

(4) pageEncoding

    该属性指定Tag文件的字符编码,其默认值是ISO-8859-1Tag文件必须使用ANSI编码保存。

2.include指令

        Tag文件中也有和JSP文件类似的include指令标记,其使用方法和作用与JSP文件中的include指令标记类似。

3.attribute指令

       Tag文件充当着可复用代码的角色,如果一个Tag文件能允许使用它的JSP页面向该Tag文件传递数据,就使得Tag文件的功能更为强大。在Tag文件中通过使用attribute指令,可以动态地向该Tag文件传递需要的数据。

  attribute指令的格式如下:

<%@attribute name="对象名字"required="true" | "false"

                            type="对象的类型"%>

      attribute指令中的name属性是必需的,该属性的值是一个对象的名字。JSP页面在调用Tag文件时,可向name属性指定的对象传递一个引用。       

         type指定对象的类型,比如:type=“java.util.Date

         需要特别注意的是,对象的类型必须带有包名,比如,不可以将java.util.Date简写为Date

        如果attribute指令中没有使用type指定对象的类型,那对象的类型是java.1ang.String类型。

       JSP页面使用Tag标记向调用的Tag文件中name属性指定的对象传递一个引用,方式如下:

      <前缀:Tag文件名字 对象名字="对象的引用"/>

     <前缀:Tag文件名字 对象名字="对象的引用">

              标记体

     </前缀:Tag文件名字>

比如,一个Tag文件MyTag.tag有如下的attribute指令:

      <%@ attributename="length" required="true" %>

那么JSP页面就可以如下使用Tag标记(假设标记的前缀为computer)调用MyTag.tag:

      <computer:MyTag length="1000"  />

       <computer:MyTag length="1000"  >

            我向Tag文件中传递的值是100

        <computer:MyTag/>

     再比如,一个Tag文件YourTag.tag已有如下的attribute指令:

<attribute  name="result"required="true" type="java.1ang.Double">

       那么JSP页面可以如下使用Tag标记(假设标记的前缀为computer)调用YourTag.tag,将一个java.1ang.Double类型对象的引用传递给YourTag.tag文件中的result对象:

 <computer:YourTagresult="<%=newDoube(666.999) %> />

       attribute指令中的required属性也是可选的,如果省略required属性,那么required的默认值是false

     当指定required的值是true时,调用该Tag文件的JSP页面必须向该Tag文件attribute指令中的name属性指定的对象传递一个引用,即当required的值是true时,如果使用

     <前缀:Tag 文件名字/>”  调用Tag文件就会出现错误。

      当指定required的值是false时,调用该Tag文件的JSP可以向该Tag文件attribute指令中的name属性指定的对象传递或不传递对象的引用。

           注意:Tag文件中不可以再定义和attribute指令中的name属性指定的对象具有相同名字的变量,否则将隐藏attribute指令中的对象,使其失效。

4.variable指令

        Tag文件通过attribute指令,可以使JSP页面在调用该Tag文件时动态地向其传递数据。

        有时候不仅希望JSP页面向Tag文件传递数据,而且希望Tag文件能返回某些数据给JSP页面。

         比如,许多JSP页面可能都需要调用某个Tag文件,来帮助处理某些数据,但不希望Tag文件负责显示处理结果,因为各个JSP页面对显示的格式可能有不同的要求。

         因此,希望Tag文件将数据的处理结果存放在某些对象中,并将这些对象返回给当前JSP页面,由JSP页面负责显示这些对象,这样做可以很好地实现数据处理和数据显示的分离。 

(1) variable指令的格式 

<%@variable  name-given="对象名字"

             variable-class="对象的类型"scope="有效范围"%>



--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

实例:

JSP文件:

<%@ page isELIgnored="false"  %> 
<%@ taglib prefix="customTag" tagdir="/WEB-INF/tags" %>

<customTag:dropdown
									 			id="classids_dropdown"
									 			dropdown_value="${requestScope.woClassids}"
									 			input_name="wo.woclassid"
									 			input_defValue="${wo.woclassid}"
									 			add_type="wocla"
									 			input1_tip="ui_EnterCode"
									 			input2_tip="ui_EnterDesc"
									 			input1_emptyTip="ui_CodeIsNull"
									 			input2_emptyTip="ui_DescIsNull"
									 			table_head1="ui_code"
									 			table_head2="ui_Description"
									 			showFilter="true"
									 			showAdd="true"
									 			/>
Tag文件:

<%-- 
Tag					Desc								  		Type	Required	Note
dropdown_value      the value shown in the drop-down     		List    true		
input_name		 	the name of input					  		String  true
input_defValue		the default value of input			  		String	false
add_type			the type of add						 	 	String  false
input1_tip			the tip message of the first input   	 	String	false		Multi_language support
input2_tip			the tip message of the second input   		String	false		Multi_language support
input1_emptyTip		tip message when the first input is empty	String	false		Multi_language support
input2_emptyTip		tip message when the second input is empty	String	false		Multi_language support
table_head1			the head of the first column				String 	false		Multi_language support
table_head2			the head of the second column				String 	false		Multi_language support
showFilter			if show filter								Boolean	false
showAdd				if show add									Boolean false
--%>
<%@ tag  isELIgnored="false"  %> 
<%@ attribute name="id" required="true"%>
<%@ attribute name="dropdown_value" rtexprvalue="true"  type="java.util.List" required="true" %>
<%@ attribute name="input_name" required="true"%>
<%@ attribute name="input_defValue" rtexprvalue="true" %>
<%@ attribute name="add_type"%>
<%@ attribute name="input1_tip" %>
<%@ attribute name="input2_tip"%>
<%@ attribute name="input1_emptyTip"%>
<%@ attribute name="input2_emptyTip"%>
<%@ attribute name="table_head1"%>
<%@ attribute name="table_head2"%>
<%@ attribute name="showFilter"%>
<%@ attribute name="showAdd"%>


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<link href="styles/custom_dropdown.css" rel="stylesheet" type="text/css" /> 
<script type="text/javascript">
$(function(){
	 function  validateAddForm(){
		 if($("#add_codes_${id}").val()==null||$("#add_codes_${id}").val()=="<s:text name='%{#attr.input1_tip}'/>"){
			 $("#add_error_${id}").text("<s:text name='%{#attr.input1_emptyTip}'/>");
			 return false;
		 }else if($("#add_desc_${id}").val()==null||$("#add_desc_${id}").val()=="<s:text name='%{#attr.input2_tip}'/>"){
		 
			 $("#add_error_${id}").text("<s:text name='%{#attr.input2_emptyTip}'/>");
			 return false;
		 }
	   return true;
   }
	var $ui = $('#custom_dropdown_${id}');
		/**
		* on focus and on click display the dropdown, 
		* and change the arrow image
		*/
		
		$ui.find('.sb_input').bind('focus click',function(){
			$ui.find('.sb_down')
			   .addClass('sb_up')
			   .removeClass('sb_down')
			   .andSelf()
			   .find('.sb_dropdown')
			   .show();
			
			$("#add_codes_${id}").removeAttr("disabled");
			$("#add_desc_${id}").removeAttr("disabled");
		});
				
		/**
		* on mouse leave hide the dropdown, 
		* and change the arrow image
		*/
				
		$(document).ready(function(){
            $(document).bind('click', Hide);
        });
        function Hide(e){
            if($(e.target).parents("#sb_dropdown_${id}").length>0||$(e.target)[0].id =="show_selection_input_${id}" )
                return; 
			$ui.find('.sb_up')
			   .addClass('sb_down')
			   .removeClass('sb_up')
			   .andSelf()
			   .find('.sb_dropdown')
			   .hide();
			inputReset();
			$("#add_codes_${id}").attr("disabled","disabled");
			$("#add_desc_${id}").attr("disabled","disabled");
	 }
	 
		
		/**
		* selecting all checkboxes
		*/
		$ui.find('.sb_dropdown').find('label[for="all"]').prev().bind('click',function(){
			$(this).parent().siblings().find(':checkbox').attr('checked',this.checked).attr('disabled',this.checked);
		});
		
		$(".input_et").focus(function(){
					$(this).attr("value","");
					$(this).removeClass("nocontent_input");
				}).blur(function(){
					if($(this).val()==null||$(this).val()==""){
						inputReset();
					}
				});;
		$("#show_selection_input_${id}").click(function(){
			$("input[name='qcode_radio_${id}'][value='${input_defValue}']").attr("checked",true);
		});
		
		//
		if($("input[name='qcode_radio_${id}']:checked").length<=0){
			$("#show_selection_input_${id}").val("");
			//$("#show_selection_input_${id}").parent().next().find("em").append("Not  Defined   ");
		}
		
		function inputReset(){
			$("input[name='qcode_radio_${id}']:checked").removeAttr("checked");
		   $("#codesDescMapping_table_${id} tbody tr").show();
		    $("#add_error_${id}").empty();
			$("#filter_codes_${id}").attr("value","<s:text name='%{#attr.input1_tip}'/>");$("#filter_codes_${id}").addClass("nocontent_input");
			$("#add_codes_${id}").attr("value","<s:text name='%{#attr.input1_tip}'/>");$("#add_codes_${id}").addClass("nocontent_input");
			
			$("#filter_desc_${id}").attr("value","<s:text name='%{#attr.input2_tip}'/>");$("#filter_desc_${id}").addClass("nocontent_input");
			$("#add_desc_${id}").attr("value","<s:text name='%{#attr.input2_tip}'/>");$("#add_desc_${id}").addClass("nocontent_input");
		}
		$("#applySelect_${id}").click(function(){
			if($("input[name='qcode_radio_${id}']:checked").length<=0){
				alert("Please choose one");
				return;
			}
			$("#show_selection_input_${id}").val($("input[name='qcode_radio_${id}']:checked").val());
			$("#show_selection_input_${id}").parent().next().find("em").empty();
			$("#show_selection_input_${id}").removeClass("nocontent_input");
			 $ui.find('.sb_up')
			   .addClass('sb_down')
			   .removeClass('sb_up')
			   .andSelf()
			   .find('.sb_dropdown')
			   .hide();
			$("#add_error_${id}").empty();
		});
		
		$("#add_btn_${id}").click(function(){
			qtypeAddFormSubmit();
		});
		//submit add form
		function qtypeAddFormSubmit() { 
            if(validateAddForm()){
				$("#qcodeAddForm_${id}").removeAttr("onsubmit");
				var type = "${add_type}";
				var qcqcode = $("#add_codes_${id}").val();
				var qcqdesc = $("#add_desc_${id}").val();
				var qclangid = "";
                 $.ajax({
                     url : "json/qcodeinsertjson.action",
                     dataType : 'json',
                     data : {
                	 type:type,
                	 qcqcode:qcqcode,
                	 qcqdesc:qcqdesc,
                	 qclangid:qclangid
                     },
                     success : function(data) {
                    	 $("#codesDescMapping_table_${id} tbody").prepend("<tr><td><input type='radio' name='qcode_radio_${id}'  value='"+qcqcode+"'/></td>"+
    						"<td>"+qcqcode+"</td>"+
    						"<td style=\"word-break: break-all;\">"+qcqdesc+"</td></tr>");
                    	 $("#add_error_${id}").text("Added successfully!");
                     },
                     error : function(XMLHttpRequest, textStatus, errorThrown) {
                    	$("#add_error_${id}").text("Same record already exist!");
                     }
                 });
            }
        }
		
		$("#filter_btn_${id}").click(function(){
			$("#codesDescMapping_table_${id} tbody tr").hide();
			
			$("table#codesDescMapping_table_${id} tbody>tr").each(function(trindex,tritem) {
				var filter_codes=$("#filter_codes_${id}").val();
				var filter_desc=$("#filter_desc_${id}").val();
				if(filter_codes==null&&filter_desc==null){
					alert("please input");
					return false;
				}
					
				var trObj=$(this).get(0);
				if(filter_codes!=null&&filter_codes!="<s:text name='%{#attr.input1_tip}'/>"&&trObj.cells[1].textContent.toLowerCase().indexOf(filter_codes.toLowerCase())>=0){
					$(this).show();
				}else if(filter_desc!=null&&filter_desc!="<s:text name='%{#attr.input2_tip}'/>"&&trObj.cells[2].textContent.toLowerCase().indexOf(filter_desc.toLowerCase())>=0)
					$(this).show();
				if(filter_codes!=null&&filter_codes=="<s:text name='%{#attr.input1_tip}'/>"&&filter_desc!=null&&filter_desc=="<s:text name='%{#attr.input2_tip}'/>")
					$("#codesDescMapping_table_${id} tbody tr").show();
					
			});
		});
	
});
</script>

<div id="custom_dropdown_${id}" class="custom_dropdown">
   	<ul style="float:left;">
   		<span class="sb_down"> </span>
		<input id="show_selection_input_${id}" name="${input_name}" class="sb_input" type="text" readonly="true" value="${input_defValue}"/>
	</ul>
	<ul style="float:left;margin-top: 8px;margin-left: 30px;margin-right:10px;"><em style="color:red;"></em></ul>
	<ul id="sb_dropdown_${id}" class="sb_dropdown" style="display:none" >
		<c:if test="${showFilter==true}">
			<li style="text-align:left;width:315px;">
				<input id="filter_codes_${id}" class="input_et nocontent_input" type="text" value="<s:text name="%{#attr.input1_tip}"/>" style="float:left;margin-right:10px;height:20px"/>
				<textarea id="filter_desc_${id}"  class="input_et nocontent_input" rows="3"  style="float:left;height:19px;padding-top:4px"><s:text name="%{#attr.input2_tip}"/></textarea>
				<span id="filter_btn_${id}" class="span_button" style="float:left;margin-top:-2px;">Filter</span>
			</li>
			<li class="dotted-line" style="margin-top:30px"></li>
		</c:if>
		
		<li style="text-align:left;">
		<table  id="codesDescMapping_table_${id}" class="dropdown_table" cellspacing="2" cellpadding="0"  style="width:100%;border-color:white;margin-top:10px;" >
			<caption style="height:5px;"><span id="applySelect_${id}" class="span_button">Apply Selected</span></caption>
			<thead bgcolor="#ddd"><td></td><td><s:text name="%{#attr.table_head1}"/></td><td><s:text name="%{#attr.table_head2}"/></td></thead>
			
			<c:forEach items="${dropdown_value}" varStatus="status" var="qcode">
				<c:if test="${qcode.qcode!=null&&qcode.qcode!=''}">
					<tr>
						<td>
							<input type="radio" name="qcode_radio_${id}" <c:if test="${qcode.qcode==input_defValue}">checked="checked"</c:if> value="${qcode.qcode}"/>
						</td>
						<td>${qcode.qcode}</td>
						<td style="word-break: break-all;">
							<c:choose>
							   <c:when test="${fn:length(qcode.qdesc)>25}">${fn:substring(qcode.qdesc, 0, 24)} ... </c:when>
							   <c:otherwise>${qcode.qdesc}</c:otherwise>
							  
							</c:choose>
						</td>
					</tr>
				</c:if> 
			</c:forEach>
			
		</table>
	
		</li>
		<div class="dotted-line"></div>
		<c:if test="${showAdd==true}">
			<form id="qcodeAddForm_${id}" name="qcodeAddForm" action="qcodeinsert.action" method="post" onsubmit="return false">
				<li style="text-align:center;width:315px;">
					<input disabled="disabled" id="add_codes_${id}" name="qc.qcode" class="input_et nocontent_input" type="text" value="<s:text name="%{#attr.input1_tip}"/>" style="float:left;margin-right:10px;height:20px'"/>
					<textarea disabled="disabled" id="add_desc_${id}" name="qc.qdesc" class="input_et nocontent_input" rows="3"  style="float:left;height:18px;padding-top:3px;"><s:text name="%{#attr.input2_tip}"/></textarea>
					<span id="add_btn_${id}" class="span_button" style="float:left;margin-left:20px;margin-top:-2px;">Add</span>
				</li>
				<li style="text-align:center;margin-top:40px;">
					<span id="add_error_${id}" style="color: red;"> </span>
				</li>
			</form>
		</c:if>
	</ul>
</div>






相关文章推荐

开发第一个JSP自定义标签(Tag)

开发和使用JSP自定义标签过程:1.开发标签实现类.  HelloTag_Interface.java文件内容:import javax.servlet.jsp.tagext.Tag;import j...
  • lip009
  • lip009
  • 2006年10月10日 22:39
  • 9292

JSP中的TAG

JSP标签有两种实现方法,一种是使用tag 文件,一种是使用tld文件。 1、使用tag文件 标签名和tag文件名一致, tag文件为JSP文件,可以有属性,把JSP页面当JavaBean文件一样使用...

Jsp 自定义tag标签

Jsp自定义tag标签自定义tag标签的好处程序员可以自定一些特定功能的标记, 用来封装代码, 达到分工, 重用性等多种好处.如何存放tag标签通常在web工程WEB-INF文件夹下创建tags文件夹...

Jsp tag file例子以及说明

简介 Jsp2.0后,实现tag的方式除了taglib(TLD)的方式外,还可以通过定义tag文件来代替taglib类。tag file一般放在/WEB-INF/tags目录或者其子目录,需要在js...

jsp tag 自定义标签实现按钮的显示

前些天在一个项目中做了一个最基本的权限管理(标准的权限结构,用户-角色-菜单),后来需要精确地控制到按钮就想到了使用自定义标签(jsp tag)来处理按钮的显示与隐藏。 下面是我参考网上的资料自己写的...

<c:import>标签说明

一、关于标签的字符编码问题: 标签是可以把其他静态(HTML,txt文件等)或是动态(JSP,PHP文件等)文件的内容包含到本身的JSP网页中,除了能够包含和自己在同一个web applicatio...
  • xwnxwn
  • xwnxwn
  • 2016年07月17日 16:24
  • 736

【Java.Web】JSP —— 标签库taglib —— 自定义JSP标签 —— JSP Tag API

JSP Tag API Servlet 容器在运行翻译JSPwen'jian

java--自定义标签(tag、tld两种)

1.一篇不错的 java自定义标签的文章地址:http://gaoshu2006.blog.sohu.com/113222643.html 2.sun公司java自定义标签原文地址:http:/...

使用JSTL开发jsp自定义标签开发

借助于jstl,我们可以方便的开发自定义标签,而不需要使用sun的jsp tag api本文以开发一个简单的if标签为例首先编写标签执行类,最重要的一点,继承javax.servlet.jsp.jst...

手把手教你做一个自定义表格标签

原帖子: http://cuisuqiang.iteye.com/blog/1582942 手把手教你做一个自定义表格标签 博客分类: J2EE开发软件 表格自定义标签grid分页tab...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:jsp中Tag的使用(自定义标签)
举报原因:
原因补充:

(最多只允许输入30个字)