Exception handling of java basic learning, a year after graduation, sprouted a new Java manufacturer experience

// The subclass method did not throw an exception

@Override

public List<String> readFromFile(String filePath){

    return null;

}

}

1.3. 2. Method overload

Java method overloading involves only method names and parameter lists. Method return value and exception list are used as the basis for method overloading.

1

2

3

4

5

6

7

8

9

10

public List<String> readFromFile(String path) throws IOException{

return null;

}

/**

Compile but

public List<String> readFromFile(String path) throws FileNotFoundException{

return null;

}

*/

1.3. 3. Constructor

Exception restriction has no effect on the constructor. The subclass constructor can throw any exception, regardless of the exception thrown by the base class constructor. However, because the base class constructor must be called in some form, the exception description of the derived class constructor must contain the exception description of the base class constructor.

The constructor will set the object to a safe initialization state. If there is other work, such as opening a file, such an action can only be cleaned up after the object is used and the user calls the cleaning method. If an exception is thrown in the constructor, these cleanup actions will not work properly, so pay special attention when writing the constructor.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

class Parent{

Parent() throws IOException{



}

}

class Child extends Parent{

Child() throws IOException {

    super(); //Exception thrown this time

}

/**

Child() throws IOException {

    // super Must be the first statement, exception cannot be caught

    try {

        super(); //Exception thrown this time

    }catch (Exception e){



    }



}

 */

}

1.4 inspected abnormality

Exceptions that are forced to be checked at compile time are called checked exceptions. That is, the exception declared in the declaration of the method.

The checked exception requires that the method caller must handle the exception. In a way, the checked exception violates the original intention of Java exception handling.

1

2

3

4

private List<String> readFromFile(String filePath) throws IOException {

Path path = Paths.get(filePath);

return Files.readAllLines(path, Charset.defaultCharset());

}

You cannot ignore the handling of the 'IOException' when calling the 'readFromFile' method.

In general, we usually handle the checked exceptions as follows:

  1. Modify your own method signature and add a new exception declaration;

  2. Use try catch to wrap exception calls (most of the time, we don't know how to recover);

  3. Convert the checked exception into a runtime exception;

1

2

3

4

5

6

7

8

9

private void printFile2(String filePath){

try {

    List&lt;String&gt; lines = readFromFile(filePath);

    lines.forEach(System.out::println);

}catch (IOException e){

    // Use the exception chain to convert checked exceptions to runtime exceptions

    throw new RuntimeException(e);

}

}

1.4.1 Spring DAO Support

There are a large number of checked exceptions in the JDBC interface. When operating the database, a large number of try catch template codes will appear, burying the core logic in the code sea.

Therefore, Spring optimizes it. The specific optimization measures are as follows:

  1. On the basis of runtime exceptions, a set of exception system (DataAccessException and subclasses) is established;

  2. Convert the checked exception in jdbc into a runtime exception;

  3. Use template method to reduce redundant code.

The JDBC tempalt code snippet is as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

public <T> T execute(StatementCallback<T> action) throws DataAccessException {

Assert.notNull(action, "Callback object must not be null");



Connection con = DataSourceUtils.getConnection(obtainDataSource());

Statement stmt = null;

try {

	stmt = con.createStatement();

	applyStatementSettings(stmt);

	T result = action.doInStatement(stmt);

	handleWarnings(stmt);

	return result;

}

catch (SQLException ex) {

	// Release Connection early, to avoid potential connection pool deadlock

	// in the case when the exception translator hasn't been initialized yet.

	String sql = getSql(action);

	JdbcUtils.closeStatement(stmt);

	stmt = null;

	DataSourceUtils.releaseConnection(con, getDataSource());

	con = null;

	// Complete the conversion from checked exception to runtime exception

	throw translateException("StatementCallback", sql, ex);

}

finally {

	JdbcUtils.closeStatement(stmt);

	DataSourceUtils.releaseConnection(con, getDataSource());

}

}

2. Custom exception

You don't have to be limited to the exception types provided by Java. We can customize exception classes to represent specific problems that may be encountered in the program.

To customize an exception class, you must inherit from an existing exception class. The best way is to select an exception class with similar meaning.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

//Business exception

class BizException extends RuntimeException{

public BizException() {

    super();

}



public BizException(String message) {

    super(message);

}



public BizException(String message, Throwable cause) {

    super(message, cause);

}



public BizException(Throwable cause) {

    super(cause);

}

}

Exceptions are usually named to represent the problem, and the name of the exception should be known by text.

2.1. Abnormal inheritance system

Exceptions themselves are classes, and there is a complete inheritance system.

2.2. Throwable

Throwable is used to represent any class that can be thrown as an exception.

Throwable objects can be divided into two types (inherited from throwable):

  • Error is used to indicate compile time and system errors. Except in special cases, developers do not need to have a relationship

  • Exception indicates the base type that can be thrown. Exceptions can be thrown in Java class libraries, user methods, and runtime faults. This is the most relevant exception for developers.

throwable is mainly used to maintain the exception stack. The core methods are as follows:

Method | meaning

—|—

printStackTrace | print call stack information and output it to standard error output (System.error)

printStackTrace(PrintStream) | specifies the Stream print call stack information

printStackTrace(PrintWriter) | specifies the Print call stack information

getStackTrace() | get call stack sequence information

fillInStackTrace() | records the current state of the stack frame

The exception stack records the method call sequence of "taking you to the exception throw point", which is one of the main information for troubleshooting.

1

2

3

4

5

6

7

8

9

10

11

public static void main(String... arg){

try {

    // Normal processing flow, correct implementation of the process, what to do

    Path path = Paths.get("var", "error");

    List&lt;String&gt; lines = Files.readAllLines(path, Charset.defaultCharset());

    System.out.println(lines);

} catch (IOException e) {

    // Exception handling process. What if something goes wrong

    e.printStackTrace();

}

}

Run the program and get the results. The exception stack is as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

java.nio.file.NoSuchFileException: var/error

at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)

at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)

at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)

at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)

at java.nio.file.Files.newByteChannel(Files.java:361)

at java.nio.file.Files.newByteChannel(Files.java:407)

at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384)

at java.nio.file.Files.newInputStream(Files.java:152)

at java.nio.file.Files.newBufferedReader(Files.java:2781)

at java.nio.file.Files.readAllLines(Files.java:3199)

at com.geekhalo.exception.Demo.main(Demo.java:15)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:483)

at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

2.3. Exception

Exception is the base class of all exception classes related to programming.

|Method | meaning|

| — | — |

|getMessage | get details|

|getLocaliedMessage | get the details of the local language representation|

2.4. RuntimeException

The exception derived from RuntimeException becomes an unchecked exception. This exception is automatically thrown by the Java virtual machine, so it does not have to be listed in the exception description of the method.

1

2

3

private void throwRuntimeException(){

throw new RuntimeException();

}

RuntimeException and its subclasses} do not need to be declared in the method.

3. Common exception handling strategies

After the custom exception is completed, the next key point is how to handle the exception.

3.1. Abnormal recovery

The purpose of the exception handler is to handle the exception that occurs. Therefore, the first exception handling strategy is to handle exceptions and recover exceptions.

1

2

3

4

5

6

7

8

9

10

11

12

13

private void recoveryException(String filePath){

try {

    List&lt;String&gt; lines = readFromFile(filePath);

    lines.forEach(System.out::println);

}catch (IOException e){

    // Print the log and recover the program from the exception

    LOGGER.error("failed to read from file {}", filePath, e);

}

}

private List<String> readFromFile(String filePath) throws IOException {

Path path = Paths.get(filePath);

return Files.readAllLines(path, Charset.defaultCharset());

}

3.2. Re throw exception

When you can't get enough information to recover the exception. You can re throw the exception just caught. The reference to the current exception object has been obtained in the catch clause and can be thrown directly.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

private void printFile(String filePath) throws IOException{

try {

    List&lt;String&gt; lines = readFromFile(filePath);

    lines.forEach(System.out::println);

}catch (IOException e){

    // Re throw exception

    throw e;

}

}

//Method exception description

private List<String> readFromFile(String filePath) throws IOException {

Path path = Paths.get(filePath);

return Files.readAllLines(path, Charset.defaultCharset());

}

Throwing the exception again will throw the exception to the previous call, and the catch clause after the same try will be ignored. If only the current exception is thrown, printStackTrace displays the call chain information of the original exception throwing point rather than the information of the re throwing point. If you want to update the invocation information, you can call the fillInStackTrace method to return another Throwable object, which will fill the current call stack information into the original exception object.

3.3. Abnormal chain

If you want to throw another new exception after catching an exception and want to keep the original exception information, this is called exception concatenation.

The subclass of Throwable can accept a cause object in the constructor to represent the original exception. In this way, the original exception is passed to the new exception, so that the new exception created and thrown in the current position can be traced to the original position of the exception through the exception chain.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

private void printFile2(String filePath){

try {

    List&lt;String&gt; lines = readFromFile(filePath);

    lines.forEach(System.out::println);

}catch (IOException e){

    // Abnormal chain

    throw new BizException(e);

}

}

//Method exception description

private List<String> readFromFile(String filePath) throws IOException {

Path path = Paths.get(filePath);

return Files.readAllLines(path, Charset.defaultCharset());

}

In the Throwable subclass, only Error, Exception and RuntimeException provide the cause parameter in the constructor. If you want to chain other exceptions, you can use the initCause method.

4. Abnormal actual combat

Exception is an indispensable point in frame design.

The exception handling in the framework also follows the fixed operation process:

  1. Customize exceptions according to requirements;

  2. Provide exception handler to handle exceptions uniformly;

4.1. Spring MVC unified exception handling

Spring MVC is the most common Web framework. It is easy to start and develop quickly.

Follow the separation strategy of normal process and exception handling. The R & D personnel only need to care about the normal logic, and the framework handles the abnormal process uniformly. How should I operate it?

4.1. 1. Define business exceptions

First, you need to define your own business exceptions.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

public abstract class BusinessException extends RuntimeException{

/**

 * Exception handling code

 */

private final int code;



/**

 * Exception message

 */

private final String msg;



private final String timestamp = String.valueOf(System.currentTimeMillis());



protected BusinessException(int code, String msg){

    this.code = code;

    this.msg = msg;

}



protected BusinessException(int code, String msg, Exception e) {

    super(e);

    this.code = code;

    this.msg = msg;

}

}

4.1. 2. Exception handling

Exceptions can be customized using the HandlerExceptionResolver extension.

RestHandlerExceptionResolver , handles the service exception requested by , Rest ,. Uniformly convert the exception into JSON and return it to the user.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

@Component

public class RestHandlerExceptionResolver implements HandlerExceptionResolver {

private static final Logger LOGGER = LoggerFactory.getLogger(RestHandlerExceptionResolver.class);



@Override

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

    // It is a Rest request and can handle it

    if(isRestRequest(handler) &amp;&amp; isAcceptException(ex)){

        // Pass exception to RestResVo object

        RestResVo&lt;Void&gt; restResVo = RestResVo.error((BusinessException)ex);

        try {

            // Writeback in Json format

            response.getWriter().println(JSON.toJSONString(restResVo));

        }catch (Exception e){

            LOGGER.error("failed to write json {}", restResVo, e);

        }

        // empty ModelAndView description has been processed

        return new ModelAndView();

    }

    return null;

}



private boolean isRestRequest(Object handler) {

    if (handler instanceof HandlerMethod){

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        return AnnotationUtils.findAnnotation(handlerMethod.getMethod(), ResponseBody.class) !=null ||

                AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), ResponseBody.class) != null;

    }

    return false;

}



private boolean isAcceptException(Exception ex) {

    return ex instanceof BusinessException;

}

}

PageHandlerExceptionResolver: handles exceptions in page requests. Uniformly forward exceptions to the error view.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

@Component

public class PageHandlerExceptionResolver implements HandlerExceptionResolver {

@Override

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

    // Is a page request and can handle the current exception

    if(isPageRequest(handler) &amp;&amp; isAcceptException(ex)){

        // Return to the error view

        ModelAndView mv =  new ModelAndView("error");

        mv.addObject("error", ex);

        return mv;

    }

    return null;

}





private boolean isPageRequest(Object handler) {

    if (handler instanceof HandlerMethod){

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        return AnnotationUtils.findAnnotation(handlerMethod.getMethod(), ResponseBody.class) == null

                &amp;&amp; AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), ResponseBody.class) == null;

    }

    return true;

}



private boolean isAcceptException(Exception ex) {

    return ex instanceof BusinessException;

}

}

4.2. Spring Cloud exception penetration

When using Spring Cloud for microservices, if an exception occurs on the Server side, the client will receive a 5xx error, thus interrupting the current normal request logic. However, the business information contained in the exception is also lost. How to keep the exception information to the greatest extent?

4.2. 1. Define business exceptions

First, you still define your own business exception class.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

@Data

public class CodeBasedException extends RuntimeException {

private Integer code;

private String msg;

private Object data;



public CodeBasedException(){

    super();

}

public CodeBasedException(String msg) {

    super(msg);

    this.msg = msg;

}



public CodeBasedException(Integer code, String msg, Object data) {

    this.code = code;

    this.msg = msg;

    this.data = data;

}



public CodeBasedException(String message, Integer code, String msg, Object data) {

    super(message);

    this.code = code;

    this.msg = msg;

    this.data = data;

}

}

4.2.2. Server side processing

On the Server side, business exceptions are captured and the information is written back through the Header.

Handlerinterceptorbasedexception binder: after the business processing is completed, catch the CodeBasedException exception and write the exception information back to the Header through the Response object.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class HandlerInterceptorBasedExceptionBinder implements HandlerInterceptor {

private static final Logger LOGGER = LoggerFactory.getLogger(HandlerInterceptorBasedExceptionBinder.class);



@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    if (ex == null){

        return;

    }

    if (ex instanceof CodeBasedException){

        CodeBasedException codeBasedException = (CodeBasedException) ex;

        response.addHeader(SoaConstants.HEADER_ERROR_CODE, String.valueOf(codeBasedException.getCode()));

        response.addHeader(SoaConstants.HEADER_ERROR_MSG, encode(codeBasedException.getMsg()));



        response.addHeader(SoaConstants.HEADER_ERROR_EXCEPTION_MSG, encode(codeBasedException.getMessage()));

        return;



    }



    response.setHeader(SoaConstants.HEADER_ERROR_CODE, "500");

    response.setHeader(SoaConstants.HEADER_ERROR_MSG, encode(ex.getMessage()));



    response.setHeader(SoaConstants.HEADER_ERROR_EXCEPTION_MSG, encode(String.valueOf(ex.getStackTrace())));

    LOGGER.error("failed to handle request.", ex);

}

}

If it is a Spring Boot project, we need to complete the registration of handlerinterceptorbasedexception binder.

1

2

3

4

5

6

7

@Configuration

public class SoaWebMvcConfigurer implements WebMvcConfigurer{

@Override

public void addInterceptors(InterceptorRegistry registry) {

    registry.addInterceptor(new HandlerInterceptorBasedExceptionBinder()).addPathPatterns("/**");

}

}

4.2.3. Client side processing

After obtaining the request result, the client extracts the exception information from the Header, reassembles and throws an exception.

Feignerroderbasedexception converter: extract the exception information from the Header, reassemble and throw a SoaRemoteCallException.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

last

Authoritative guide - the first Docker book

Lead the installation, deployment, management and expansion of Docker, let it go through the whole development life cycle from test to production, and deeply understand what scenarios Docker is suitable for. In addition, this authoritative guide to Docker introduces the basic knowledge of its components, and then uses Docker to build containers and services to complete various tasks: use Docker to establish a test environment for new projects, demonstrate how to integrate Docker using continuously integrated workflow, how to build application services and platforms, how to use Docker's API, and how to extend Docker.

It includes nine chapters: introduction, installing Docker, getting started with Docker, using Docker image and warehouse, using Docker in testing, using Docker to build services, using Fig to configure Docker, using Docker API, getting help and improving Docker.

The "K8S+Docker learning guide" strongly recommended by Ali - Kubernetes in simple terms: Theory + practice and authoritative guide - the first Docker book are described in two words after reading. I love it!

CodeChina open source project: [analysis of Java interview questions of front-line large manufacturers + core summary learning notes + latest explanation Video]

);

    LOGGER.error("failed to handle request.", ex);

}

}

If it is a Spring Boot project, we need to complete the registration of handlerinterceptorbasedexception binder.

1

2

3

4

5

6

7

@Configuration

public class SoaWebMvcConfigurer implements WebMvcConfigurer{

@Override

public void addInterceptors(InterceptorRegistry registry) {

    registry.addInterceptor(new HandlerInterceptorBasedExceptionBinder()).addPathPatterns("/**");

}

}

4.2.3. Client side processing

After obtaining the request result, the client extracts the exception information from the Header, reassembles and throws an exception.

Feignerroderbasedexception converter: extract the exception information from the Header, reassemble and throw a SoaRemoteCallException.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

last

Authoritative guide - the first Docker book

Lead the installation, deployment, management and expansion of Docker, let it go through the whole development life cycle from test to production, and deeply understand what scenarios Docker is suitable for. In addition, this authoritative guide to Docker introduces the basic knowledge of its components, and then uses Docker to build containers and services to complete various tasks: use Docker to establish a test environment for new projects, demonstrate how to integrate Docker using continuously integrated workflow, how to build application services and platforms, how to use Docker's API, and how to extend Docker.

It includes nine chapters: introduction, installing Docker, getting started with Docker, using Docker image and warehouse, using Docker in testing, using Docker to build services, using Fig to configure Docker, using Docker API, getting help and improving Docker.

[external chain picture transferring... (img-6T7C6sfb-1630462751591)]

[external chain picture transferring... (img-p8321CtP-1630462751593)]

[external chain picture transferring... (img-T1qxnMJz-1630462751595)]

[external chain picture transferring... (img-dtV4gT47-1630462751598)]

The "K8S+Docker learning guide" strongly recommended by Ali - Kubernetes in simple terms: Theory + practice and authoritative guide - the first Docker book are described in two words after reading. I love it!

CodeChina open source project: [analysis of Java interview questions of front-line large manufacturers + core summary learning notes + latest explanation Video]

Keywords: Java Spring Back-end mvc

Added by willc on Sat, 18 Dec 2021 01:27:15 +0200