Archive for the ‘计算机技术’ Category

26
Sep

centos中nginx+subversion的解决方案

   Posted by: zu

由于nginx不支持http方式访问subversion。也就是没有扩展。所以我们只能用svn协议来访问版本库。

其实平时也用不上http的版本库访问。那就干脆直接用svn协议了。配置起来也方便。

1.安装subversion

yum install subversion

2.建立版本库,本例中我们的版本库建立在/var/www/svn,假设该版本库目录为bbs

cd /var/www

mkdir svn

svnadmin create bbs

3.配置

刚才建立了bbs这个svn版本库,需要配置的有通用认证方式,用户名和密码,权限配置这三个文件,分别是/var/www/svn/bbs下的conf下的svnserve.conf passwd 和authz这三个文件。

svnserve.conf:

anon-access = none
auth-access = write
password-db = passwd
authz-db = authz.conf

passwd文件:
user1:password1
user2:password2

authz文件:
[groups]
bbsuser = user1,user2
[bbs:/]
@bbsuser = rw
* = 

其中*=意味着匿名用户没有权限

4.启动
配置成功以后,启动svn版本库服务
svnserve -d -r /var/www/svn

5.使用
svn co http://192.160.0.1/bbs
即可取得版本库

19
Sep

mongodb 读写文件。

   Posted by: zu

<project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sf</groupId>
  <artifactId>mavenproject1</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>mavenproject1</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongo-java-driver</artifactId>
      <version>2.6.5</version>
    </dependency>
  </dependencies>
</project>
—-
package com.sf.mavenproject1;
import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSInputFile;
 
public class App {
    public static void main(String[] args) {
        try {
            Mongo mongo = new Mongo(“localhost”, 27017);
            DB db = mongo.getDB(“imagedb”);
            DBCollection collection = db.getCollection(“dummyColl”);
            String newFileName = “mkyong-java-image”;
            File imageFile = new File(“c:\\Blue hills.jpg”);
            // create a “photo” namespace
            GridFS gfsPhoto = new GridFS(db, “photo”);
            // get image file from local drive
            GridFSInputFile gfsFile = gfsPhoto.createFile(imageFile);
            // set a new filename for identify purpose
            gfsFile.setFilename(newFileName);
            // save the image file into mongoDB
            gfsFile.save();
            // print the result
            DBCursor cursor = gfsPhoto.getFileList();
            while (cursor.hasNext()) {
                System.out.println(cursor.next());
            }
            // get image file by it’s filename
            GridFSDBFile imageForOutput = gfsPhoto.findOne(newFileName);
            // save it into a new image file
            imageForOutput.writeTo(“c:\\JavaWebHostingNew.png”);
            // remove the image file from mongoDB
            gfsPhoto.remove(gfsPhoto.findOne(newFileName));
            System.out.println(“Done”);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (MongoException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

When learning Object-oriented programming, two of the concepts are fairly difficult to understand and therefore to digest : classes must be loosely coupled and highly cohesive. In today’s post, I am going to explain why this is important and how Sonar can help you evaluating how cohesive are your classes.

A few weeks ago, I started a discussion on how to Fight Back Design Erosion by Breaking Cycles with Sonar in which I mentioned that good design should enable to replace any part of a system by a new piece of code with little pain. The first aspect to look at is really the “macro level”, i.e. packages, to ensure for instance that there are no cycles between packages. But to obtain modularity at any level of the design you also need to consider the “micro level”, i.e. the classes / methods, by keeping it loosely coupled and highly cohesive.

Coupling is the degree to which each class is tight to the others. In other words if a class is highly coupled, any change you make to this class can have direct or indirect impact on many other classes : not what I would call great modularity ! You can use for example the inversion of control principle to reduce the coupling between classes.

Cohesion is the degree to which the methods of a single class are tight together. When two methods in a class do not use a common attribute or a common method, it means that they share nothing and should probably not belong to the same class to respect the Single Responsibility Principle. In other words you can split your class into several new classes to gain modularity at class level.

So whereas classes should be very unrelated with lowest possible coupling, methods should on the opposite be strongly related with high possible cohesion. This is pretty similar to an agile organization : each team (class) should be very autonomous (low coupling) but all members (methods) of a team should be very tight to each other (high cohesion).

Sonar 2.0 comes with a new experimental and very promising metric : LCOM4 (Lack Of Cohesion Methods) to measure how cohesive classes are. Interpreting this metric is pretty simple as value 1 means that a class has only one responsibility (good) and value X means that a class has probably X responsibilities (bad) and should be refactored/split.

There is not any magic here, only common sense. Let’s take a simple example with class Driver. This class has two fields : Car and Brain, and five methods : drive(), goTo(), stop(), getAngry() and drinkCoffee(). Here is the dependency graph between those components. There are three blocks of related components, so LCOM4 = 3, so the class seems to have three different responsibilities and breaks the Single Responsibility Principle.

When it comes to Sonar, things remain pretty simple. A first widget is available within the project dashboard to get a quick insight :

From there, you can click to drill down and view the suspect classes. Knowing the LCOM4 value of a class is a good starting point but definitely not sufficient. Click on the class you are interested in and you will be presented with the block of cohesive methods :

Refactoring can start !

While writing this post, II found out a great post from Stuart Gunter : Assessing the Single Responsibility Principle with LCOM4 with Sonar 2.0. This is a post on “Sonar’s LCOM4 in action” that gives us good feedback on how to improve our algorithm to compute this experimental but valuable metric. 

27
Jun

Spring2.5 注解介绍(3.0通用)

   Posted by: zu

注解说明

注册注解处理器

方式一:bean

<bean class=”org.springframework.beans.factory.annotation.
AutowiredAnnotationBeanPostProcessor”/>

方式二: 命名空间<context:annotation-config />

<context:annotationconfig /> 将隐式地向Spring 容器注册AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor PersistenceAnnotationBeanPostProcessor 以及RequiredAnnotationBeanPostProcessor4BeanPostProcessor

方式三: 命名空间<context:component-scan />

如果要使注解工作,则必须配置component-scan ,实际上不需要再配置annotation-config。

base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。还允许定义过滤器将基包下的某些类纳入或排除。

 

 

Spring 支持以下4 种类型的过滤方式:

              注解 org.example.SomeAnnotation 将所有使用SomeAnnotation 注解的类过滤出来

              类名指定 org.example.SomeClass 过滤指定的类

              正则表达式 com.kedacom.spring.annotation.web..* 通过正则表达式过滤一些类

              AspectJ 表达式 org.example..*Service+ 通过AspectJ 表达式过滤一些类

 

 

正则表达式的过滤方式举例:

<context:component-scanbase-package=”com.casheen.spring.annotation”>

<context:exclude-filtertype=”regex”
expression=”com.casheen.spring.annotation.web..*”/>
</context:component-scan>

注解的过滤方式举例:

<context:component-scan base-package=”com.netqin” >

<context:include-filter type=”annotation”
expression=”org.springframework.stereotype.Controller”/>
<context:include-filter type=”annotation”
expression=”org.springframework.stereotype.Service”/>
<context:include-filter type=”annotation”
expression=”org.springframework.stereotype.Repository”/>

</context:component-scan>

 

启用Spring MVC 注解

启动Spring MVC 的注解功能,完成请求和注解POJO 的映射

<bean class=”org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter”/>


 

注解介绍

              @Controller

              @Service

              @Autowired

              @RequestMapping

              @RequestParam

              @ModelAttribute

              @Cacheable

              @CacheFlush

              @Resource

              @PostConstruct

              @PreDestroy

              @Repository

              @Component (不推荐使用)

              @Scope

              @SessionAttributes

              @InitBinder

              @Required

              @Qualifier

 


 

@Controller

              例如

              @Controller
              public class SoftCreateController extends SimpleBaseController {}

              或者
             @Controller(“softCreateController”)

              说明

              @Controller 负责注册一个beanspring 上下文中,beanID 默认为类名称开头字母小写

 


 

@Service

              例如

              @Service
              public class SoftCreateServiceImpl implements ISoftCreateService {}

              或者
              @Service(“softCreateServiceImpl”)

              说明

              @Service 负责注册一个beanspring 上下文中,beanID 默认为类名称开头字母小写

 


 

@Autowired

              例如

              @Autowired
              private ISoftPMService softPMService;

              或者

 

     @Autowired(required=false)
     private ISoftPMService softPMService = new SoftPMServiceImpl();

 

         • 说明

    @Autowired 根据bean 类型从spring 上线文中进行查找,注册类型必须唯一,否则报异常。与@Resource 的区别在于,@Resource 允许通过bean 名称或bean 类型两种方式进行查找@Autowired(required=false) 表示,如果spring 上下文中没有找到该类型的bean 时, 才会使用new SoftPMServiceImpl();

@Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 id 或 name 作为 Map 的 key。

@Autowired 还有一个作用就是,如果将其标注在 BeanFactory 类型、ApplicationContext 类型、ResourceLoader 类型、ApplicationEventPublisher 类型、MessageSource 类型上,那么 Spring 会自动注入这些实现类的实例,不需要额外的操作。


 

@RequestMapping

@Controller
@RequestMapping(“/bbtForum.do”)

public class BbtForumController {
             @RequestMapping(params = “method=listBoardTopic”)

public String listBoardTopic(int topicId,User user) {}
}

 

  方法

              @RequestMapping(“/softpg/downSoftPg.do”)
              @RequestMapping(value=”/softpg/ajaxLoadSoftId.do”,method = POST)
              @RequestMapping(value = “/osu/product/detail.do”, params = { “modify=false” }, method =POST)

  说明
    @RequestMapping
可以声明到类或方法上

 

参数绑定说明
如果我们使用以下的 URL 请求:

http://localhost/bbtForum.do?method=listBoardTopic&topicId=1&userId=10&userName=tom

topicId URL 参数将绑定到 topicId 入参上,而 userId userName URL 参数将绑定到 user 对象的 userId userName 属性中。和 URL 请求中不允许没有 topicId 参数不同,虽然 User userId 属性的类型是基本数据类型,但如果 URL 中不存在 userId 参数,Spring 也不会报错,此时 user.userId 值为 0 。如果 User 对象拥有一个 dept.deptId 的级联属性,那么它将和 dept.deptId URL 参数绑定。


 

@RequestParam

参数绑定说明
@RequestParam(“id”)

http://localhost/bbtForum.do?method=listBoardTopic&id=1&userId=10&userName=tom

listBoardTopic(@RequestParam(“id”)int topicId,User user) 中的 topicId 绑定到 id 这个 URL 参数, 那么可以通过对入参使用 @RequestParam 注解来达到目的

 

@RequestParam(required=false):参数不是必须的,默认为true

@RequestParam(value=”id”,required=false)

 

 

请求处理方法入参的可选类型

              Java 基本数据类型和 String

                    默认情况下将按名称匹配的方式绑定到 URL 参数上,可以通过 @RequestParam 注解改变默认的绑定规则

 

              request/response/session

 既可以是 Servlet API 的也可以是 Portlet API 对应的对象,Spring 会将它们绑定到Servlet Portlet 容器的相应对象上

 

org.springframework.web.context.request.WebRequest

 内部包含了 request 对象

 

java.util.Locale

绑定到 request 对应的 Locale 对象上

 

        java.io.InputStream/java.io.Reader

                可以借此访问 request 的内容

 

        java.io.OutputStream / java.io.Writer

可以借此操作 response 的内容

 

         任何标注了 @RequestParam 注解的入参

                被标注 @RequestParam 注解的入参将绑定到特定的 request 参数上。

 

         java.util.Map / org.springframework.ui.ModelMap

它绑定 Spring MVC 框架中每个请求所创建的潜在的模型对象,它们可以被 Web 视图对象访问(如 JSP

 

         命令/ 表单对象(注:一般称绑定使用 HTTP GET 发送的 URL 参数的对象为命令对象,而称绑定使用HTTP POST 发送的 URL 参数的对象为表单对象)

                     它们的属性将以名称匹配的规则绑定到 URL 参数上,同时完成类型的转换。

                     而类型转换的规则可以通过 @InitBinder 注解或通过 HandlerAdapter 的配置进行调


  
org.springframework.validation.Errors / org.springframework.validation.BindingResult

                     为属性列表中的命令/ 表单对象的校验结果,注意检验结果参数必须紧跟在命令/ 表单对象的后面

 

    org.springframework.web.bind.support.SessionStatus

 可以通过该类型 status 对象显式结束表单的处理,这相当于触发 session 清除其中的通过@SessionAttributes 定义的属性

 

请求处理方法返回值的可选类型

void

此时逻辑视图名由请求处理方法对应的 URL 确定,如以下的方法:
@RequestMapping(“/welcome.do”)
public void welcomeHandler() {}
对应的逻辑视图名为
welcome

String

此时逻辑视图名为返回的字符,如以下的方法:
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam(“ownerId”) int ownerId, ModelMap model) {

Owner owner = this.clinic.loadOwner(ownerId);
model.addAttribute(owner);
return “ownerForm”;

}
对应的逻辑视图名为 ownerForm

org.springframework.ui.ModelMap

和返回类型为 void 一样,逻辑视图名取决于对应请求的 URL ,如下面的例子:
@RequestMapping(“/vets.do”)
public ModelMap vetsHandler() {

return new ModelMap(this.clinic.getVets());

}

对应的逻辑视图名为 vets ,返回的 ModelMap 将被作为请求对应的模型对象,可以在 JSP 视图页面中访问到。

 

ModelAndView
当然还可以是传统的 ModelAndView


 

@ModelAttribute

              作用域:request

              例如
             @RequestMapping(“/base/userManageCooper/init.do”)

             public String handleInit(@ModelAttribute(“queryBean”) ManagedUser sUser,Model model,){

              或者

              @ModelAttribute(“coopMap”)// coopMap 返回到页
          
public Map<Long,CooperatorInfo> coopMapItems(){}

              说明

 

@ModelAttribute 声明在属性上,表示该属性的value 来源于model“queryBean” ,并被保存到model@ModelAttribute 声明在方法上,表示该方法的返回值被保存到model


 

@Cacheable @CacheFlush

              @Cacheable :声明一个方法的返回值应该被缓
             
例如:@Cacheable(modelId = “testCaching”)

              @CacheFlush :声明一个方法是清空缓存的触发器
                
例如:@CacheFlush(modelId = “testCaching”)

              说明

               要配合缓存处理器使用,参考: http://hanqunfeng.iteye.com/blog/603719

 

 

@Resource

              例如

              @Resource
              private DataSource dataSource; // inject the bean named ‘dataSource’

              或者

 

@Resource(name=”dataSource”)
@Resource(type=DataSource.class)

 

说明

@Resource 默认按beanname 进行查找,如果没有找到会按type 进行查找,
此时与@Autowired

在没有为 @Resource 注解显式指定 name 属性的前提下,如果将其标注在 BeanFactory 类型、ApplicationContext 类型、ResourceLoader 类型、ApplicationEventPublisher 类型、MessageSource 类型上,那么 Spring 会自动注入这些实现类的实例,不需要额外的操作。此时 name 属性不需要指定 ( 或者指定为”"),否则注入失败;

@PostConstruct @PreDestroy

@PostConstruct

在方法上加上注解@PostConstruct ,这个方法就会在Bean 初始化之后被Spring 容器执
(注:Bean 初始化包括,实例化Bean ,并装配Bean 的属性(依赖注入))。

@PreDestroy
在方法上加上注解@PreDestroy ,这个方法就会在Bean 被销毁前被Spring 容器执行。


 

@Repository

@Controller@Service 类似,都是向spring 上下文中注册bean ,不在赘述。


 

@Component (不推荐使用)

@Component

@Component 是所有受Spring 管理组件的通用形式,Spring 还提供了更加细化的注解形式:  @Repository@Service@Controller ,它们分别对应存储层Bean ,业务层Bean ,和展示层Bean

目前版本(2.5 )中,这些注解与@Component 的语义是一样的,完全通用, Spring 以后的版本中可能会给它们追加更多的语义。 所以,我们推荐使用@Repository@Service@Controller 来替代@Component


 

@Scope

              例如

                @Scope(“session”)

                @Repository()

                public class UserSessionBean implementsSerializable {}

 

              说明

 

在使用XML 定义Bean 时,可以通过beanscope 属性来定义一个Bean 的作用范围,
同样可以通过@Scope 注解来完成

       @Scope中可以指定如下值:

       singleton:定义bean的范围为每个spring容器一个实例(默认值)

       prototype:定义bean可以被多次实例化(使用一次就创建一次)

       request:定义bean的范围是http请求(springMVC中有效)

       session:定义bean的范围是http会话(springMVC中有效)

       global-session:定义bean的范围是全局http会话(portlet中有效)

 

@SessionAttributes

说明

Spring 允许我们有选择地指定 ModelMap 中的哪些属性需要转存到 session 中,
以便下一个请求属对应的 ModelMap 的属性列表中还能访问到这些属性。
这一功能是通过类定义处标注 @SessionAttributes 注解来实现的。
@SessionAttributes
只能声明在类上,而不能声明在方法上。

 

例如

@SessionAttributes(“currUser”) // ModelMap 中属性名为currUser 的属性
@SessionAttributes({“attr1″,”attr2″})
@SessionAttributes(types = User.class)
@SessionAttributes(types = {User.class,Dept.class})
@SessionAttributes(types = {User.class,Dept.class},value={“attr1″,”attr2″})

@InitBinder

说明

如果希望某个属性编辑器仅作用于特定的 Controller
可以在 Controller 中定义一个标注 @InitBinder 注解的方法,
可以在该方法中向 Controller 了注册若干个属性编辑器

 

例如

@InitBinder
public void initBinder(WebDataBinder binder) {

SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));

}

 

 

@Required

              例如

              @required              

              public  setName(String name){}

              说明

              @ required 负责检查一个bean在初始化时其声明的 set方法是否被执行, 当某个被标注了 @Required 的 Setter 方法没有被调用,则 Spring 在解析的时候会抛出异常,以提醒开发者对相应属性进行设置。 @Required 注解只能标注在 Setter 方法之上。因为依赖注入的本质是检查 Setter 方法是否被调用了,而不是真的去检查属性是否赋值了以及赋了什么样的值。如果将该注解标注在非 setXxxx() 类型的方法则被忽略。

 

@Qualifier

              例如

              @Autowired

              @Qualifier(“softService”)
              private ISoftPMService softPMService;

 

         • 说明

            使用@Autowired 时,如果找到多个同一类型的bean,则会抛异常,此时可以使用 @Qualifier(“beanName”),明确指定bean的名称进行注入,此时与 @Resource指定name属性作用相同。

 

参考资料

              jdk1.5 注解介绍

              http://hi.baidu.com/gaoyaodi/blog/item/4cee6cf4706f2dddf3d385cd.html

              spring2.5 注解

http://www.infoq.com/cn/articles/spring-2.5-part-1
http://www.infoq.com/cn/articles/spring-2.5-ii-spring-mvc

spring3.0 注解

       http://tech.ddvip.com/2010-05/1273461026153068.html